首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwingUtilities.invokeAndWait不等待吗?

SwingUtilities.invokeAndWait不等待吗?
EN

Stack Overflow用户
提问于 2012-05-25 10:21:28
回答 3查看 662关注 0票数 2

下面的代码运行良好

代码语言:javascript
复制
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更新中发现了类似的问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-11 23:27:42

如果您查看EventQueue.invokeAndWait的实现,您将看到它没有正确地处理虚假唤醒。它调用lock.wait(),然后不检查runnable是否实际完成了执行--这意味着invokeAndWait可以在runnable完成执行之前返回!

出于某种原因,在mac上的更新31中,虚假唤醒已经开始以合理的频率发生,暴露了EventQueue中这个长期存在的错误。我不知道发生了什么变化,它没有发生在任何其他版本的Java。

我们通过使用一个简单的布尔检查来实现我们自己的invokeAndWait方法来修复这个问题。

票数 3
EN

Stack Overflow用户

发布于 2012-05-25 10:31:05

我的SSCCE:

代码语言:javascript
复制
public abstract class FunctionRunnable<V> implements Runnable {
  private V result;
  private Throwable thr;

  protected abstract V calculate();

  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;
  }

  public static void main(String[] args) throws Exception {
    final FunctionRunnable<Boolean> runnable = new FunctionRunnable<Boolean>() {
      public Boolean calculate() { return doCalculation(); }
      private boolean doCalculation() {
        try { Thread.sleep(2000); } catch (InterruptedException e) {}
        return false;
      }};
    SwingUtilities.invokeAndWait(runnable);
    System.out.println(runnable.getResult().booleanValue());
  }
}

我的Java版本:

代码语言:javascript
复制
$java -version
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)

启动,运行2秒,打印false

票数 3
EN

Stack Overflow用户

发布于 2012-05-28 11:21:42

我有时会得到NullPonterExeption..。怪异

java版本"1.6.0_31“Java(TM) SE运行时环境(build 1.6.0_31-b04-415-11M3635) Java HotSpot(TM)客户端VM (build 20.6-b01-415,混合模式)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10752672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档