Java中CompletableFuture的whenComplete回调未执行原因咨询
问题原因分析
你的代码里犯了一个很容易忽略的细节错误:你调用completeExceptionally()的对象,并不是你添加whenComplete回调的那个原始CompletableFuture实例。
CompletableFuture的所有回调方法(包括whenComplete)都会返回一个新的CompletableFuture实例,而不是修改原对象。你的代码里,future变量实际指向的是whenComplete返回的新实例,而最初new CompletableFuture<Void>()创建的那个实例根本没有被保存下来——你对这个新实例调用completeExceptionally()毫无意义,因为它的状态完全由上游的原始实例决定,而原始实例从未被完成过,所以回调自然不会触发。
修正后的代码
把原始的CompletableFuture单独保存,再对它调用completeExceptionally():
import java.util.concurrent.*; public class TestCompletableFuture { public static void main(String[] args) throws Exception { // 保存原始的CompletableFuture实例 CompletableFuture<Void> originalFuture = new CompletableFuture<>(); // 对原始实例添加回调 originalFuture.whenComplete((res, exc) -> { System.out.println("inside handle."); if (exc != null) { System.out.println("exception."); } System.out.println("completed."); }); // 对原始实例调用completeExceptionally originalFuture.completeExceptionally(new Exception("exception")); System.out.println("finished."); } }
运行后输出会符合预期:
inside handle. exception. completed. finished.
补充说明:whenComplete的回调默认会在调用completeExceptionally()的线程(这里是主线程)中执行,所以回调会在completeExceptionally()调用后立即触发,之后才会打印finished.。
内容的提问来源于stack exchange,提问作者SL Official
相关产品推荐
相关产品推荐

