CompletableFuture 全面详解
2025-08-17 本文已影响0人
_浅墨_
一、概念
CompletableFuture 是 Java 8 引入的 异步编程工具类,位于 java.util.concurrent 包下,是 Future 接口的增强版。
传统 Future 的问题:
-
阻塞获取结果:必须调用
get()才能拿到结果,且可能阻塞线程。 - 无法链式处理:不能在结果出来后自动触发下一步操作。
- 缺乏组合能力:多个异步任务的组合很不方便。
👉 CompletableFuture 解决了这些问题:
- 支持非阻塞回调(异步计算完成后自动执行回调)。
- 提供链式调用(类似 Java Stream)。
- 可以组合多个任务(并行、串行、任意完成)。
- 灵活控制线程池,避免阻塞主线程。
二、适用场景
-
并行调用多个服务接口
- 例如:查询用户信息时,同时调用「基本信息服务」「积分服务」「订单服务」,然后合并结果。
-
任务依赖与组合
- 一个任务完成后自动执行另一个任务(A → B → C)。
-
超时控制 & 异常处理
- 某个接口超时/失败时,可以降级处理。
-
替代复杂的回调地狱(Callback Hell)
- 用链式写法让异步逻辑更清晰。
三、核心方法分类
| 方法 | 用途 | 示例 |
|---|---|---|
runAsync(Runnable) |
异步执行,无返回值 | 日志异步写入 |
supplyAsync(Supplier) |
异步执行,有返回值 | 远程服务调用 |
thenApply(Function) |
任务完成后,处理返回值 | result -> result * 2 |
thenAccept(Consumer) |
任务完成后,消费结果,无返回 | 打印结果 |
thenRun(Runnable) |
任务完成后,执行额外逻辑 | 写日志 |
thenCombine/thenCompose |
组合多个任务 | 合并查询结果 |
allOf/anyOf |
等待所有 / 任意任务完成 | 聚合服务结果 |
exceptionally/handle |
异常处理 | 超时降级 |
四、实战示例
1. 基础异步调用
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时任务
sleep(1000);
return "用户数据";
});
// 非阻塞回调
future.thenAccept(result ->
System.out.println("处理结果: " + result)
);
// 主线程继续执行
System.out.println("主线程未被阻塞");
Thread.sleep(2000);
输出:
主线程未被阻塞
处理结果: 用户数据
2. 并行调用多个接口 → 聚合结果
CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> {
sleep(1000);
return "用户信息";
});
CompletableFuture<String> orderFuture = CompletableFuture.supplyAsync(() -> {
sleep(1500);
return "订单信息";
});
CompletableFuture<String> result = userFuture.thenCombine(orderFuture,
(user, order) -> user + " | " + order);
System.out.println("最终结果: " + result.get());
输出:
最终结果: 用户信息 | 订单信息
3. 任意一个任务完成即返回
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
sleep(1000);
return "接口1响应";
});
CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> {
sleep(2000);
return "接口2响应";
});
CompletableFuture<Object> result = CompletableFuture.anyOf(f1, f2);
System.out.println("最快的结果: " + result.get());
输出:
最快的结果: 接口1响应
4. 异常处理
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
if (true) throw new RuntimeException("服务调用失败");
return 42;
}).exceptionally(ex -> {
System.out.println("异常: " + ex.getMessage());
return -1; // 降级返回
});
System.out.println("结果: " + future.get());
输出:
异常: java.lang.RuntimeException: 服务调用失败
结果: -1
五、最佳实践建议
-
指定线程池
CompletableFuture.supplyAsync(task, executor); -
异常必须处理
- 使用
exceptionally或handle
- 使用
-
避免阻塞 get()
- 建议用回调代替
future.get()。
- 建议用回调代替
-
复杂任务用组合 API
- 使用
thenCombine、thenCompose、allOf、anyOf。
- 使用
✅ 总结:
CompletableFuture 是 Java 异步编程的核心工具,尤其适用于高并发场景、服务聚合、超时降级。