爪哇猪笼草。invokeAndWait不等待?
下面的代码运行良好
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();
在苹果发布1.6.0_31之前,我们应用程序的用户有时会在最后一行获得NPE
您是否在代码中看到了bug,或者其他人是否发现了与此特定Java更新类似的问题
# 1 楼答案
我有时会被剥夺权利。。。。诡异的
java版本“1.6.0_31” Java(TM)SE运行时环境(build 1.6.0_31-b04-415-11M3635) Java HotSpot(TM)客户端虚拟机(构建20.6-b01-415,混合模式)
# 2 楼答案
我的SSCCE:
我的Java版本:
启动,运行2秒钟,打印
false
# 3 楼答案
如果您关注EventQueue的实现。invokeAndWait您将看到它无法正确处理虚假唤醒。它叫锁。wait()则不检查runnable是否实际完成了执行——这意味着invokeAndWait可以在runnable完成执行之前返回
出于某种原因,mac os上的update 31开始以合理的频率出现虚假唤醒,暴露了EventQueue中这个长期存在的漏洞。我不确定发生了什么变化,这在任何其他版本的Java中都不会发生
我们通过实现我们自己的invokeAndWait方法来解决这个问题,方法是对runnable的完成进行简单的布尔检查