CompletableFuture 会在我执行 get 并抛出异常时自动取消吗?

CompletableFuture does it cancel automatically when I do a get and an exception is thrown?

我在我的代码中做了类似下面的事情。

CompletableFuture<FOObar> f =  doSomething();
Foobar foo = f.get(timeout, TimeUnit.MILLISECONDS);

如果get抛出任何Exception,无论是TimeoutException还是其他,未来会发生什么。是默认取消,还是应该取消

try {
f.get(timeout, TimeUnit.MILLISECONDS);
}
catch {
  f.cancel(true);
}

因此未来被释放。 如果我不明确取消,未来是否会挂在线程上,如果所有线程都停留在该状态,最终会导致饥饿

我需要阻塞 get,因为我需要 foo 来执行进一步的逻辑。

根据 JavaDoc,调用 get(timeout, unit) 时可能出现 4 种异常:

  • CancellationException - 如果这个未来被取消
  • ExecutionException - 如果这个 future 异常完成
  • InterruptedException - 如果当前线程在等待时被中断
  • TimeoutException - 如果等待超时

ExecutionException 是最直接的一个:future completed execeptionnally,这通常意味着任务以抛出异常结束(但也可能意味着其他事情以异常完成了 future)。

后2个与get()调用本身的等待有关,它们只是表示在抛出异常时future还没有完成。

CancellationException 表示未来已 cancel()ed,但不表示作业是否仍然 运行。

问题是默认情况下调用 cancel(boolean) 不会取消 运行 作业,即使参数是 true:

Parameters

mayInterruptIfRunning - this value has no effect in this implementation because interrupts are not used to control processing.

因此,默认情况下,您是否调用 cancel() 并不重要,因为它不会影响 运行 作业。

如果你想停止 运行 作业,你必须在创建 CompletableFuture 的方法中实现一个特定的机制来支持它(这里是 doSomething())。例如,它可以检查返回的 future 是否被取消,或者提供一些其他回调机制来停止执行(例如,通过在某处设置 stop 标志)。