简单的完整future.supplyasync()导致IllegalMonitorStateException错误

发布于 2025-02-11 02:41:36 字数 814 浏览 2 评论 0原文

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

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

I'm trying this in 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();
  }

Upon running, I got this output:

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)

Is the "error" information expected? Did I miss anything in my code snippet?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

国际总奸 2025-02-18 02:41:36

等待方法从对象类派生。如果需要使用它,则需要监视对象。

就您而言,您不需要监视,但是您需要“等待完整的未来完成”。在这种情况下,您需要从等待切换到get方法。

The wait method derives from the Object class. If you need to use it, you need to monitor the object.

In your case, you should not need to monitor, but you need to 'wait for the completable future to complete'. In this case you need to switch from wait to get method.

眉目亦如画i 2025-02-18 02:41:36

显示堆栈跟踪的异常由future.wait()抛出,并且与错误参数参数无关。之所以发生,是因为wait()要求将其调用的线程持有对象的监视器。参见有关线程成为对象监视器的所有者的含义的说明。您的代码基本上必须在同步块中,以便能够调用wait()notify()。您可能打算调用get()wait()/notify()方法是object object继承的通用同步方法,并且已经存在自Java开始以来。

至于错误参数,它的确是空的,因为第一阶段正常完成。因此,行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) {
    ...
}

The exception whose stack trace is shown is thrown by future.wait() and is not related to the error argument of the second CompleableFuture. It occurs because wait() requires the thread invoking it to be holding the object's monitor. See this for a description of what it means for a thread to be owner of the object's monitor. Your code basically has to be within a synchronized block in order to be able to call wait() or notify(). You probably intended to call get(), the wait()/notify() methods are generic synchronization methods inherited by Object and have been there since the beginning of Java.

As for the error parameter, it is indeed null, because the first stage completes normally. Hence, the line error.printStackTrace() should thrown a NPE. However, your code simply does not handle. It is thrown in the async thread that executes the stage, and remains silent. See this post in relation to this behavior.

I suspect you want to call the get() method on the future. First you should assign the second stage to a variable (future is still referencing the first stage):

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

Then you could call get() on it, which allows you to handle an ExecutionException which will wrap the NPE occurring in the second stage:

try {
    result = future.get();
    System.out.println(result);
} catch (InterruptedException e) {
    ...
} catch (ExecutionException e) {
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文