[英]Simple CompletableFuture.supplyAsync() leads to IllegalMonitorStateException error
I'm trying this in java8:我在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?
我错过了代码片段中的任何内容吗?
The wait
method derives from the Object
class. wait
方法派生自Object
类。 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.在这种情况下,您需要从
wait
切换到get
方法。
The exception whose stack trace is shown is thrown by future.wait()
and is not related to the error
argument of the second CompleableFuture
.显示堆栈跟踪的异常由
future.wait()
抛出,并且与第二个CompleableFuture
的error
参数无关。 It occurs because wait()
requires the thread invoking it to be holding the object's monitor.这是因为
wait()
要求调用它的线程持有对象的监视器。 See this for a description of what it means for a thread to be owner of the object's monitor.有关线程成为对象监视器的所有者意味着什么的描述,请参阅this 。 Your code basically has to be within a
synchronized
block in order to be able to call wait()
or notify()
.您的代码基本上必须在
synchronized
块内才能调用wait()
或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.您可能打算调用
get()
, wait()/notify()
方法是由Object
继承的通用同步方法,并且从 Java 开始就一直存在。
As for the error
parameter, it is indeed null, because the first stage completes normally.至于
error
参数,确实是null,因为第一阶段正常完成。 Hence, the line error.printStackTrace()
should thrown a NPE.因此,
error.printStackTrace()
行应该抛出一个 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.我怀疑你想在未来调用
get()
方法。 First you should assign the second stage to a variable ( future
is still referencing the first stage):首先,您应该将第二阶段分配给一个变量(
future
仍然引用第一阶段):
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:然后你可以在它上面调用
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.