【问题标题】:Simple CompletableFuture.supplyAsync() leads to IllegalMonitorStateException error简单的 CompletableFuture.supplyAsync() 导致 IllegalMonitorStateException 错误
【发布时间】:2022-06-30 14:17:06
【问题描述】:

我正在 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)

是否需要“错误”信息?我在我的代码 sn-p 中遗漏了什么吗?

【问题讨论】:

  • Object#wait 方法来自另一个宇宙(同步/等待/通知),我相信你需要使用 get() 方法。

标签: java exception monitor completable-future


【解决方案1】:

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

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

【讨论】:

  • 或者使用join()
【解决方案2】:

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

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

我怀疑你想在未来调用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) {
    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多