繁体   English   中英

简单的 CompletableFuture.supplyAsync() 导致 IllegalMonitorStateException 错误

[英]Simple CompletableFuture.supplyAsync() leads to IllegalMonitorStateException error

我在java8中尝试这个:

  public static void main(String[] args) throws Exception {
    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(
      () -> { return 911; });
    future.whenComplete(
      (result, error) -> {
        System.out.println("Alarm:" + result);
        error.printStackTrace();
      }
    );
    future.wait();
  }

运行后,我得到了这个输出:

Alarm:911
[WARNING]
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait (Native Method)
    at java.lang.Object.wait (Object.java:502)
    at mygroup.UseCompletableFuture.main (UseCompletableFuture.java:15)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:254)
    at java.lang.Thread.run (Thread.java:748)

是否需要“错误”信息? 我错过了代码片段中的任何内容吗?

wait方法派生自Object类。 如果你需要使用它,你需要监控对象。

在您的情况下,您不需要监控,但您需要“等待可完成的未来完成”。 在这种情况下,您需要从wait切换到get方法。

显示堆栈跟踪的异常由future.wait()抛出,并且与第二个CompleableFutureerror参数无关。 这是因为wait()要求调用它的线程持有对象的监视器。 有关线程成为对象监视器的所有者意味着什么的描述,请参阅this 您的代码基本上必须在synchronized块内才能调用wait()notify() 您可能打算调用get()wait()/notify()方法是由Object继承的通用同步方法,并且从 Java 开始就一直存在。

至于error参数,确实是null,因为第一阶段正常完成。 因此, error.printStackTrace()行应该抛出一个 NPE。 但是,您的代码根本无法处理。 它被抛出在执行阶段的异步线程中,并保持沉默。 有关此行为,请参阅此帖子

我怀疑你想在未来调用get()方法。 首先,您应该将第二阶段分配给一个变量( future仍然引用第一阶段):

future = future.whenComplete(
      (result, error) -> {
        System.out.println("Alarm:" + result);
        System.out.println(error);
        error.printStackTrace();
      }
);

然后你可以在它上面调用get() ,它允许你处理一个ExecutionException ,它将包装在第二阶段发生的 NPE:

try {
    result = future.get();
    System.out.println(result);
} catch (InterruptedException e) {
    ...
} catch (ExecutionException e) {
    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM