一文讲透 CompletableFuture:Future 的真正进化版
Java 8的CompletableFuture是增强版异步编程工具,解决了传统Future的阻塞获取、缺乏回调等问题。它支持异步执行、结果获取、链式任务编排(thenApply/thenCompose)、多任务组合(allOf/anyOf)、异常处理等特性。通过supplyAsync/runAsync启动任务,结合then系列方法实现任务流水线,还能自定义线程池。相比Future/FutureT
在前面我们已经讲清楚了:
-
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 才是真正的异步编排与任务组合框架。
更多推荐



所有评论(0)