Java CompletableFuture

CompletableFuture 如何组合异步任务、传递异常与配置执行器:避免阻塞式回调地狱。

#type / concept #status / growing #tech / dev #resource / java

[!info] 关联笔记

Java CompletableFuture

这个概念为什么出现

Future.get() 会阻塞;多依赖组装易成回调泥潭。CompletableFuture 提供声明式异步组合:thenApply/thenCompose/exceptionally 等,把任务图表达清楚。

[!abstract] 一句话理解 CompletableFuture 是可手动完成、可组合的异步结果;组合链要显式指定 Executor,并统一处理异常与超时。

最小可运行示例

场景:并行查库存与价格,再汇总下单视图

import java.util.concurrent.*;

public class OrderViewAsync {
    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        try {
            CompletableFuture<Integer> stock = CompletableFuture.supplyAsync(() -> 3, pool);
            CompletableFuture<Integer> price = CompletableFuture.supplyAsync(() -> 100, pool);
            CompletableFuture<String> view = stock.thenCombineAsync(price,
                    (s, p) -> "stock=" + s + ",price=" + p, pool);
            System.out.println(view.get(1, TimeUnit.SECONDS));
        } finally {
            pool.shutdown();
        }
    }
}

建议运行:

javac OrderViewAsync.java && java OrderViewAsync

期望输出:

stock=3,price=100

结合场景再看三个关注点

  1. supplyAsync 指定 pool,别默认打满 commonPool。
  2. thenCombine 表达汇合
  3. get 设超时,防永久阻塞。

核心概念与准确模型

1. 创建

  • supplyAsync / runAsync / completedFuture

2. 组合

  • thenApply 变换
  • thenCompose 扁平嵌套异步
  • thenCombine 两路汇合
  • allOf/anyOf

3. 异常

  • exceptionally / handle / whenComplete
  • 未处理异常在 get 时以 ExecutionException 出现

4. 超时

  • orTimeout / completeOnTimeout(版本相关)

边界情况与反直觉行为

  1. 链上线程落在哪取决于 Async 后缀与 Executor。
  2. 阻塞式调用塞进 commonPool 会饿死。
  3. 取消语义有限,需协作。

常见误区

[!warning] 常见误区:在 thenApply 里做重阻塞 IO 还不换池 IO 用专用 Executor 或虚拟线程策略。

工程实践

  1. 每条业务异步边界明确线程池。
  2. 统一包装异常为领域错误。
  3. 指标记录耗时与超时。
  4. 与响应式库边界分清,不混风格。

本节总结

  • CF=异步组合工具
  • Executor + 超时 + 异常
  • 汇合与扁平化是核心技能

自测题

  1. thenApply 与 thenCompose 差在哪?
  2. 为什么要避免默认 commonPool 跑阻塞任务?
参考答案
  1. apply 映射值;compose 用于返回另一个 CompletionStage 并扁平化。
  2. commonPool 被阻塞会拖垮其它并行任务。

延伸阅读与资料来源

资料类型支撑内容
CompletableFuture APIAPI组合方法
创建于 2026/7/15 更新于 2026/7/15