下面您会看到一些运行良好的代码 - 但只能运行一次。它应该阻塞直到 runOnUIThread 完成。当它第一次运行时它被调用时确实如此。但是当第二次调用时,它会一直运行到最后,然后 runOnUIThread 开始运行。可能是,该方法第一次运行后,调用它的线程仍然拥有锁,当它第二次调用该方法时,它就跑通了。这是正确的吗?我能做些什么来解决这个问题?或者是时序问题,第二次调用者先获得锁?
static Integer syn = 0;
@Override
public String getTanFromUser(long accid, String prompt) {
// make parameters final
final long accid_int = accid;
final String prompt_int = prompt;
Runnable tanDialog = new Runnable() {
public void run() {
synchronized(syn) {
tanInputData = getTANWithExecutionStop(TransferFormActivity.this);
syn.notify() ;
}
}
};
synchronized(syn) {
runOnUiThread(tanDialog);
try {syn.wait();}
catch (InterruptedException e) {}
}
return tanInputData;
}
后台:调用此方法的线程是绑定(bind)服务内的异步任务,该服务正在后台与银行进行交易。银行不定期地发送用户验证请求(验证码、控制问题、PIN 请求等),并且服务必须通过对前台 Activity 的弱引用回调显示一些对话框。由于服务正在执行多个嵌套的 while 循环,因此同步显示对话框比停止重新启动服务更容易(保存/恢复状态数据太复杂)。
最佳答案
您可以尝试一下,如果在 FutureTask
中使用 Callable
而不是 Runnable
效果更好。据我所知,这种组合意味着提供线程的返回值。
public String getTanFromUser(long accid, String prompt) {
// make parameters final
final long accid_int = accid;
final String prompt_int = prompt;
Callable<String> tanDialog = new Callable<String>() {
public String call() throws Exception {
return getTANWithExecutionStop(TransferFormActivity.this);
}
};
FutureTask<String> task = new FutureTask<String>(tanDialog);
runOnUiThread(task);
String result = null;
try {
result = task.get();
}
catch (InterruptedException e) { /* whatever */ }
catch (ExecutionException e) { /* whatever */ }
return result;
}
一个Callable
类似于 Runnable
但有返回值。
一个FutureTask
进行同步并等待结果。与您的 wait()
/notify()
类似。 FutureTask
还实现了 Runnable
,因此它可用于 runOnUiThread
。
关于android - 多线程应用程序中的同步阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13182397/