在前面我们已经讲清楚了:

  • Runnable / Callable 是任务

  • Future 是取异步结果的凭证

  • FutureTask 是任务+结果的执行体

但是传统 Future 有致命缺陷:

  • get() 是阻塞的(同步)

  • 不支持回调

  • 不支持链式操作

  • 不支持多个任务组合(allOf / anyOf)

  • 不支持异步异常处理

  • 不支持 A 完成后执行 B(缺乏编排能力)

为了解决这些问题,Java 8 引入了:

CompletableFuture:Java 最强异步编排工具

它本质是:

Future + Promise + 异步回调 + 任务编排 + 异步线程池
的综合体,是 Java 最现代的异步编程模型。

1. CompletableFuture 能做什么?(最重要)

能力 Future FutureTask CompletableFuture
异步执行 ✔️ ✔️ ✔️
获取结果 ✔️ ✔️ ✔️
回调(任务完成自动触发) ✔️
链式任务组合 thenApply ✔️
异步组合 thenCompose ✔️
多任务组合 allOf / anyOf ✔️
异常处理 exceptionally ✔️
自定义线程池 ✔️
完成结果(手动完成) ✔️

它是 Java 官方承认的“下一代 Future”。

CompletableFuture<Integer> f =
        CompletableFuture.supplyAsync(() -> {
            return 42;
        });

2. CompletableFuture 的四种基础方法(异步执行任务)

这是你最常用的:

1)runAsync(无返回值)

CompletableFuture<Void> f =
        CompletableFuture.runAsync(() -> {
            System.out.println("任务执行:" + Thread.currentThread().getName());
        });

2)supplyAsync(有返回值)

CompletableFuture<Integer> f =
        CompletableFuture.supplyAsync(() -> {
            return 42;
        });

3)自定义线程池版本

CompletableFuture.supplyAsync(() -> calc(), myExecutor);
 

4)同步完成结果

CompletableFuture 既能异步也能手动完成:

CompletableFuture<String> f = new CompletableFuture<>();
f.complete("OK");   // 手动设置结果

这点是 Future / FutureTask 做不到的。

3. CompletableFuture 的杀手级功能:任务编排

Future 最大的缺点就是不能像 Promise 一样 chain(链式)

CompletableFuture 完全解决了这个问题。

(1)thenApply:A 完成 → 用结果做 B

CompletableFuture.supplyAsync(() -> 10)
    .thenApply(n -> n + 1)
    .thenApply(n -> n * 2)
    .thenAccept(System.out::println); // 22

非常像 JavaScript 的 Promise。


(2)thenCompose:异步嵌套(flatMap)

两个异步任务串联:

CompletableFuture.supplyAsync(() -> getUserId())
    .thenCompose(id -> CompletableFuture.supplyAsync(() -> loadUser(id)))

解决回调地狱。

(3)thenCombine:两个任务并行 → 合并结果

CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> 20);

f1.thenCombine(f2, (a, b) -> a + b)
  .thenAccept(System.out::println);  // 30

这是 Future 完全无法做到的。

(4)allOf:多个任务全部完成

CompletableFuture.allOf(f1, f2, f3)
    .thenRun(() -> System.out.println("全部完成"));

(5)anyOf:谁快用谁

CompletableFuture.anyOf(f1, f2, f3)
    .thenAccept(result -> System.out.println("最快的:" + result));

适合多个来源选最快结果。

4. CompletableFuture 的强大异常处理

传统 Future 只能在 get() 阻塞抛异常。

CompletableFuture 可以:

① 异常回调:

future.exceptionally(e -> {
    e.printStackTrace();
    return -1;
});

② 异常与正常结果统一处理

future.handle((res, ex) -> {
    if (ex != null) return -1;
    return res + 1;
});

③ 任务链自动异常传播(类似 try-catch)

5. CompletableFuture 的真正学习关键:异步 + 编排

未来写 Java 异步代码的核心:

supplyAsync -> thenApply -> thenCompose -> thenCombine -> exception -> allOf

示例(一条链):

CompletableFuture.supplyAsync(() -> queryUser())
    .thenCompose(user -> loadOrders(user.id))
    .thenCombine(loadCoupons(), (orders, coupons) -> merge(orders, coupons))
    .thenApply(result -> enhance(result))
    .exceptionally(e -> handleError(e))
    .thenAccept(finalResult -> System.out.println(finalResult));

这是一段 Future 永远写不出的代码。

6. CompletableFuture 会替代 Future 吗?

答案:

是的,在异步编排场景中,CompletableFuture 已经完全替代 Future。

线程池的语义从:

submit(callable) → Future

进化为:

CompletableFuture.supplyAsync(callable)
 

7. 文章总结(最关键的部分)

功能 Future CompletableFuture
异步结果 ✔️ ✔️
阻塞等待 ✔️ ✔️
回调 ✔️
链式调用 ✔️
多任务组合 ✔️
异常链处理 ✔️
自定义线程池 ✔️
手动完成任务 ✔️
当 Promise 用 ✔️

一句记住:

Future 是只能 get 的“老式异步模型”。
CompletableFuture 才是真正的异步编排与任务组合框架。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐