为什么调用 CompletableFuture::cancel 会导致立即 CancellationException

Dar*_*ius 0 java concurrency java.util.concurrent java-8 completable-future

我想打电话给cancelCompletableFuture

从文档看来:

如果尚未完成,则使用 CancellationException 完成此 CompletableFuture。尚未完成的从属 CompletableFutures 也将异常完成,此 CancellationException 会导致 CompletionException。

它应该异常地完成它们,这正是我所期望的,但相反,它会立即抛出 CancellationException。

这是一个示例代码

CompletableFuture<?> f = CompletableFuture.supplyAsync(() -> false);
f.cancel(true);  // Line 7.
f.join();
Run Code Online (Sandbox Code Playgroud)

使用重现:https : //www.mycompiler.io/view/2v1ME4u

Exception in thread "main" java.util.concurrent.CancellationException
    at java.base/java.util.concurrent.CompletableFuture.cancel(CompletableFuture.java:2396)
    at Main.main(Main.java:7)
Run Code Online (Sandbox Code Playgroud)

7号线是f.cancel(true);线。

And*_*ner 5

它实际上不会立即抛出。

调用f.cancel(true)导致 aCancellationException创建,捕获调用的堆栈跟踪cancel。所以堆栈跟踪(因为它未处理而被打印)包含f.cancel(true);调用的行。

但直到f.join()

完成时返回结果值,如果异常完成则抛出(未经检查的)异常

...

抛出:

CancellationException - 如果计算被取消

您可以通过在示例代码中添加更多打印语句来查看这一点:

CompletableFuture<?> f = CompletableFuture.supplyAsync(() -> false);
f.cancel(true);  // Line 8.
try {
    f.join();
} catch (CancellationException e) {
    System.out.println("CancellationException was thrown at call to f.join()");
    e.printStackTrace(System.out);
}
Run Code Online (Sandbox Code Playgroud)

输出:

CancellationException was thrown at call to f.join()
java.util.concurrent.CancellationException
    at java.base/java.util.concurrent.CompletableFuture.cancel(CompletableFuture.java:2396)
    at Main.main(Main.java:8)
Run Code Online (Sandbox Code Playgroud)