【问题标题】:Why does calling CompletableFuture::cancel cause an immediate CancellationException为什么调用 CompletableFuture::cancel 会立即导致 CancellationException
【发布时间】:2021-11-01 04:05:27
【问题描述】:

我正在尝试在CompletableFuture 上致电cancel

从文档看来:

如果尚未完成,则使用 CancellationException 完成此 CompletableFuture。尚未完成的依赖 CompletableFuture 也将异常完成,并由此 CancellationException 引发 CompletionException。

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

这是一个示例代码

CompletableFuture<?> f = CompletableFuture.supplyAsync(() -> false);
f.cancel(true);  // Line 7.
f.join();

有一个再现: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)

第 7 行是 f.cancel(true); 行。

【问题讨论】:

  • 希望您不要介意,我将您的示例代码简化为一个更简单的示例。
  • @AndyTurner 哈哈我很感激编辑应该有这个我自己 TBH 但可惜你打败了我:)

标签: java java-8 concurrency java.util.concurrent completable-future


【解决方案1】:

它实际上并没有立即抛出。

调用f.cancel(true)创建一个CancellationException,捕获调用cancel 的堆栈跟踪。因此堆栈跟踪(由于未处理而被打印)包含f.cancel(true); 调用的行。

但直到f.join() 才真正引发该异常:

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

...

投掷:

CancellationException - 如果计算被取消

您可以通过添加更多打印语句into your example code 来看到这一点:

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);
}

输出:

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)

【讨论】:

  • 天啊,堆栈跟踪确实让我着迷,因为它说 ` at ... at Main.main(Main.java:40)` 这是取消调用的行
  • @Darius 是的,这有点臭。我原以为它是一个 CancellationException,原因是第 40 行的异常。
  • 是的,“异常情况发生在哪里”、“异常对象在哪里创建”和“它在哪里抛出”之间的细微差别可能会导致一些混乱,尤其是@987654331 @。喜欢this Q&A
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 2022-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
相关资源
最近更新 更多