我发现 CompletableFuture::join
在未完成时似乎不可中断:
// CompletableFuture::join implementation from JDK 8 sources
public T join() {
Object r;
return reportJoin((r = result) == null ? waitingGet(false) : r);
}
在上面的实现中,waitingGet(false)
会忽略正在工作的Thread
的中断标志并继续等待。我想知道如何中断调用 CompletableFuture::join
的 Thread
。
最佳答案
如果要支持中断,请不要使用 join()
,请改用 get()
。基本上它们是相同的,除了:
join()
仅在CompletableFuture
中定义,而get()
来自接口(interface)Future
join()
将异常包装在CompletionException
中,而get()
将它们包装在ExecutionException
中
get()
可能会被中断,然后会抛出一个InterruptedException
请注意,您中断的是Thread
,而不是Future
。例如,以下代码在等待 myFuture.get()
时中断主线程:
CompletableFuture<Void> myFuture = new CompletableFuture<>();
Thread mainThread = Thread.currentThread();
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
System.out.println("Interrupting…");
mainThread.interrupt();
Thread.sleep(1000);
System.out.println("Completing");
myFuture.complete(null);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
myFuture.get();
System.out.println("Get succeeded");
} catch (Exception e) {
System.out.println("Get failed");
e.printStackTrace();
}
输出:
Interrupting…
Get failed
java.lang.InterruptedException
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:347)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
at CompletableFutureInteruption.main(CompletableFutureInteruption.java:37)
…
如果将get()
替换为join()
,中断确实不会起作用。
关于java - 如何中断 CompletableFuture::join?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44231376/