为什么会有 CompletableFuture?它是为了解决什么痛点的?
前言
在 Java 的并发世界里,我们曾经习惯使用 Future
来表示“将来可能得到的结果”。但使用久了你就会发现——Future
就像一个“没长大的孩子”:
- 👉 你必须主动去阻塞等待结果(
调用 get()
),浪费了宝贵的线程资源。 - 👉 它不能链式组合多个任务,每一步都得手动管理。
- 👉 想要处理异步计算的异常?不好意思,没有太多好办法。
- 👉 想要多个任务之间协调?代码一团乱麻。
于是,CompletableFuture 横空出世,像是 Java 并发工具箱中的“全能王”。
CompletableFuture 能做什么?为什么它这么香?
-
🔄 链式异步编排:可以像搭积木一样,把多个异步操作串起来 (
thenApply
,thenCompose
,thenCombine
…),逻辑清晰、优雅。 -
💡 非阻塞处理结果:无需再
get()
阻塞等待,可以用回调处理结果,提升性能。 -
❗ 统一处理异常:通过
exceptionally
,handle
等方法,优雅应对失败情况。 -
🤝 多个任务协同执行:比如
allOf
,anyOf
,让你轻松管理多个并发任务。 -
⚙️ 与线程池无缝结合:结合
Executor
灵活指定线程策略,让异步任务更加可控。我们总结下
CompletableFuture 提供了:特性 说明 非阻塞异步编程 支持在任务完成后自动执行下一步(回调机制) 任务组合 多个任务之间可以顺序执行、并行执行、合并结果 链式调用 使用 .thenApply()
,.thenCompose()
,.thenAccept()
等方法构建建任务链异常处理 .exceptionally()
,.handle()
处理失败情况超时控制 .orTimeout()
.completeOnTimeout()
等方法一句话:CompletableFuture 是 Java 8 引入的一个重要类,属于 java.util.concurrent 包,它的出现是为了解决 异步编程 和 回调地狱(Callback Hell) 的问题,并提供更强大、更灵活的 并发任务编排能力。
用它的场景有哪些?
- 🔍 异步调用远程服务(比如微服务之间调用)
- 💼 多个接口并发调用聚合数据
- 🎬 任务编排、流程控制(如用户下单、扣库存、发短信)
- 💥 高并发、高吞吐的业务处理场景
- 📉 非阻塞化改造传统阻塞代码,释放线程资源
- 🔍异步任务执行(不阻塞主线程)
- 💼服务组合调用(多个子系统的数据合并处理)
- 🎬Web 请求处理(如 Spring WebFlux 或高并发场景)
- 💥异步 I/O 操作(如数据库/网络)
- 📉构建复杂异步任务流水线(pipeline)
- 🔍响应式编程(Reactive)中间层支持
使用示例
- 基本用法:异步执行任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 耗时计算return "Hello";
});future.thenAccept(result -> {System.out.println("结果: " + result);
});
- 任务组合:先执行 A,再执行 B
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello").thenApply(result -> result + " World"); // 继续处理结果future.thenAccept(System.out::println); // 输出: Hello World
- 两个任务并行执行,合并结果
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");CompletableFuture<String> combined = future1.thenCombine(future2, (a, b) -> a + " " + b);combined.thenAccept(System.out::println); // 输出: Hello World
- 异常处理
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {if (true) throw new RuntimeException("出错了");return "正常结果";
}).exceptionally(ex -> {return "默认值";
});future.thenAccept(System.out::println); // 输出: 默认值
和 Future 的对比总结
功能 | Future | CompletableFuture |
---|---|---|
异步任务 | ✅ | ✅ |
阻塞获取结果 | ✅(get()) | ✅(get()) |
非阻塞回调 | ❌ | ✅ |
任务链式编排 | ❌ | ✅ |
多任务组合 | ❌ | ✅ |
异常处理 | ❌ | ✅ |
超时控制 | 有限支持 | ✅ |