以下代码工作正常

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/

10-12 23:37