Multithreading J2ME-如何使线程返回一个值,并在该线程完成后,在其他操作中使用该返回值?
我有一些关于线程使用的问题,特别是当你必须等待一个线程完成,以便你可以执行其他操作时 在我的应用程序中,我使用线程进行诸如http连接之类的操作,或者在读取或写入记录存储时使用线程 例如,在我用来初始化线程的以下类中,我使用名为HttpQueryCustomers的方法从Web服务检索一些客户Multithreading J2ME-如何使线程返回一个值,并在该线程完成后,在其他操作中使用该返回值?,multithreading,java-me,Multithreading,Java Me,我有一些关于线程使用的问题,特别是当你必须等待一个线程完成,以便你可以执行其他操作时 在我的应用程序中,我使用线程进行诸如http连接之类的操作,或者在读取或写入记录存储时使用线程 例如,在我用来初始化线程的以下类中,我使用名为HttpQueryCustomers的方法从Web服务检索一些客户 public class thrLoadCustomers implements Runnable { private RMSCustomer mRMSCustomer;
public class thrLoadCustomers implements Runnable {
private RMSCustomer mRMSCustomer;
private String mUrl;
public thrLoadCustomers(RMSCustomer rmsCust, String url) {
mRMSCustomer = rmsCust;
mUrl = url;
}
public void run() {
String jsonResultados = "";
try {
jsonResultados = HttpQueryCustomers();
} catch (IOException ex) {
//How to show a message from here??
} catch (SecurityException se) {
//How to show a message here??
} catch (NullPointerException npe) {
//How to show a message from here??
}
if (!jsonResultados.equals("")) {
try {
mRMSCustomer.save(jsonResultados);
} catch (RecordStoreException ex) {
//How to show a message from here???
}
}
}
public String HttpQueryCustomers() throws IOException,SecurityException,NullPointerException {
StringBuffer stringBuffer = new StringBuffer();
HttpConnection hc = null;
InputStream is = null;
System.out.println(mUrl);
try {
hc = (HttpConnection) Connector.open(mUrl);
if (hc.getResponseCode() == HttpConnection.HTTP_OK) {
is = hc.openInputStream();
int ch;
while ((ch = is.read()) != -1) {
stringBuffer.append((char) ch);
}
}
} finally {
is.close();
hc.close();
}
String jsonData = stringBuffer.toString();
return jsonData.toString();
}
}
请注意,在上面的类中,我传递了一个名为rmsCust的参数,其类型为RMSCustomer
RMSCustomer是我用来处理与RMS相关的所有操作的类:
public class RMSCustomer {
private String mRecordStoreName;
private Customer[] mCustomerList;
public RMSCustomer(String recordStoreName) {
mRecordStoreName = recordStoreName;
}
public Customer[] getCustomers() {
return mCustomerList;
}
public Customer get(int index) {
return mCustomerList[index];
}
public void save(String data) throws RecordStoreException,JSONException,NullPointerException {
RecordStore rs = null;
int idNuevoRegistro;
String stringJSON;
try {
rs = RecordStore.openRecordStore(mRecordStoreName, true);
JSONArray js = new JSONArray(data);
//Set the size of the array
mCustomerList = new Customer[js.length()];
for (int i = 0; i < js.length(); i++) {
JSONObject jsObj = js.getJSONObject(i);
stringJSON = jsObj.toString();
idNuevoRegistro = addRecord(stringJSON, rs);
//Add a new Customer to the array
mCustomerList[i] = initializeCustomer(stringJSON, idNuevoRegistro);
}
} finally {
if (rs != null) {
rs.closeRecordStore();
}
}
}
public int addRecord(String stringJSON, RecordStore rs) throws JSONException,RecordStoreException {
byte[] raw = stringJSON.getBytes();
int idNuevoRegistro = rs.addRecord(raw, 0, raw.length);
return idNuevoRegistro;
}
public Customer initializeCustomer(String stringJSON, int idRecord) throws JSONException {
Customer c = new Customer();
JSONObject jsonObj = new JSONObject(stringJSON);
// Set Customer properties
//...
return c;
}
}
下面是我遇到的问题:
showWaitForm()
不起作用(它将一个带有仪表的窗体设置为
(当前表格)t.join()
是否是最佳选择 public class WSResult {
private boolean success; //true if the WS call went ok, false otherwise
private String errorMessage; //Error message to display if the WS call failed.
private Object result; //Result, only if the WS call succeeded.
private boolean completed = false;
//TODO getter and setters methods here
}
class LoadCustomersTask implements Runnable {
private final WSResult result;
public LoadCustomersTask(WSResult res){
result = res;
}
public void run(){
//Do the WS call
//If it went well
result.setSuccess(true);
result.setResult(jsonResultados);
//Else
result.setSuccess(false);
result.setErrorMessage("Your error message");
//In any case, mark as completed
result.setcompleted(true);
//And notify awaiting threads
synchronized(result){
result.notifyAll();
}
}
}
在屏幕中,您可以创建result的实例并等待它:
WSResult result = new WSResult();
//Start thread here
new Thread(new LoadCustomersTask(result)).start();
//This is old school thread sync.
synchronized(result){
while(!result.isCompleted()){
result.wait();
}
}
//Here the thread has returned, and we can diaplay the error message if any
if(result.isSuccess()){
} else {
//Display result.getErrorMessage()
}
那么您的runnable将如下所示:
public class WSResult {
private boolean success; //true if the WS call went ok, false otherwise
private String errorMessage; //Error message to display if the WS call failed.
private Object result; //Result, only if the WS call succeeded.
private boolean completed = false;
//TODO getter and setters methods here
}
class LoadCustomersTask implements Runnable {
private final WSResult result;
public LoadCustomersTask(WSResult res){
result = res;
}
public void run(){
//Do the WS call
//If it went well
result.setSuccess(true);
result.setResult(jsonResultados);
//Else
result.setSuccess(false);
result.setErrorMessage("Your error message");
//In any case, mark as completed
result.setcompleted(true);
//And notify awaiting threads
synchronized(result){
result.notifyAll();
}
}
}
您也可以使用thread.join来完成,但是wait/notify更好,因为您不需要让屏幕依赖于运行runnable的特定线程。您可以在结果实例上等待/通知,如图所示,或者在runnable上等待/通知(如果该实例仅用于一次使用)
问题#4:是的,线程不能被滥用,特别是在JavaME中,程序通常在单核CPU中运行,频率为MHz。尽量不要同时运行超过1-3个线程。如果你真的需要,考虑使用一个线程来运行所有后台任务(阻塞队列)。我会将这些概念移植到后台或重新实现。@Davidermann这些类不可用,我建议您不要尝试编写DIY替换代码,除非您在并发编程方面非常有经验。@MisterSmith先生这些类的源代码是可用的。请您解释一下这些行:
synchronized(result)
和结果。等待()
;在我的回答中,我使用Object.wait/Object.notify
而不是Thread.sleep/Thread.interrupt
来协调线程。您可以阅读更多关于差异的信息,但想法是一样的:一个线程等待第二个线程完成。无论何时调用wait/notify,都需要同步块,否则会引发异常。非常感谢@Mister Smith,我按照您的建议做了,现在我有了一个更有条理的代码。