以下代码工作正常
abstract class FunctionRunnable<V> implements Runnable {
protected abstract V calculate();
private V result;
private Throwable thr;
public synchronized final void run() {
try {
result = calculate();
}
catch (Throwable thr) {
this.thr = thr;
}
}
public synchronized final V getResult() {
if (thr != null) {
throw new RuntimeException(thr);
}
return result;
}
}
...
final FunctionRunnable<Boolean> runnable = new FunctionRunnable<Boolean>() {
public Boolean calculate() {
return doCalculation();
}
private boolean doCalculation() {
...
}
});
SwingUtilities.invokeAndWait(runnable);
final Boolean resultObj = runnable.getResult();
final boolean result = resultObj.booleanValue();
直到Apple发布1.6.0_31,为此我们的应用程序用户有时在最后一行获得NPE。
您是否在代码中看到错误,或者其他人在此特定的Java更新中是否发现了类似的问题?
最佳答案
如果查看EventQueue.invokeAndWait的实现,您将看到它无法正确处理虚假唤醒。它调用lock.wait()然后不检查可运行对象是否实际完成执行-这意味着invokeAndWait可以在您的可运行对象完成执行之前返回!
由于某些原因,在Mac OS上的更新31中,杂散唤醒已经开始以合理的频率发生,从而暴露了EventQueue中这个长期存在的错误。我不确定发生了什么变化,在任何其他版本的Java中都不会发生。
我们通过使用简单的 boolean 检查来实现可运行对象的完成,来实现自己的invokeAndWait方法来解决此问题。
关于java - SwingUtilities.invokeAndWait不等待吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10752672/