Java 线程池(第十篇):(收官篇)CompletableFuture 异步编排实战 —— 多任务并行、结果汇总、超时控制与线程池协作

completableFuture 异步编排实战 —— 多任务并行、结果汇总、超时控制与线程池协作

如果说前 1–9 篇解决的是 “线程池如何安全、稳定地跑”
那么这一篇解决的是:

如何把多个异步任务“编排”成一个可读、可控、可维护的并发流程。

这正是现代 Java 并发从 ThreadPoolExecutor → CompletableFuture 的进化方向。

一、为什么需要 CompletableFuture?

先看一个你一定写过的代码:

Future<User> f1 = pool.submit(() -> this.loadUser()); Future<User> f2 = pool.submit(() -> this.loadUser()); User user = f1.get(); Order order = f2.get(); 

问题很明显:

  • get() 阻塞
  • 顺序代码读起来像同步
  • 异常处理零散
  • 任务依赖一多,代码迅速失控

CompletableFuture 的核心价值只有一句话:

用“声明式”的方式,描述异步任务之间的关系,而不是用 get() 等结果。

二、CompletableFuture 和线程池的关系(先搞清楚)

1️⃣ CompletableFuture ≠ 线程池

  • CompletableFuture 是 异步任务编排工具
  • 线程池是 执行引擎

2️⃣ 默认线程池是 ForkJoinPool(不推荐直接用)

CompletableFuture.supplyAsync(() -> work()); 

默认使用:

ForkJoinPool.commonPool() 

👉 生产环境强烈建议:显式传入你自己的线程池(第五篇)

CompletableFuture.supplyAsync(() -> work(), ioPool); 

三、最核心的三种编排模式(80% 场景)

1️⃣ thenApply —— 单任务链式变换

CompletableFuture .supplyAsync(() -> 1, pool) .thenApply(x -> x + 1) .thenApply(x -> x * 2) .thenAccept(System.out::println); 
  • 同一条任务链
  • 上一步完成 → 执行下一步
  • 适合 数据转换

2️⃣ thenCompose —— 依赖型异步(避免嵌套)

CompletableFuture<User> f = loadUserAsync(id) .thenCompose(user -> loadProfileAsync(user)); 

等价于(但比它优雅得多):

CompletableFuture<User> f = loadUserAsync(id) .thenApply(user -> loadProfileAsync(user)) .get(); // ❌ 

一句话:

thenCompose = “异步版的 flatMap”

3️⃣ thenCombine —— 并行任务结果合并(非常常用)

CompletableFuture<User> userFuture = loadUserAsync(id); CompletableFuture<Order> orderFuture = loadOrderAsync(id); CompletableFuture<UserInfo> result = userFuture.thenCombine(orderFuture, (user, order) -> new UserInfo(user, order)); 

✔ 并行执行
✔ 都完成后才合并
✔ 没有 get()

四、allOf / anyOf:真正的“并行编排”

allOf:全部完成

CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3); all.thenRun(() -> System.out.println("all done")); 

⚠ 注意:allOf 不帮你收集结果,你需要自己 get(或 join)

List<Result> results = List.of(f1, f2, f3) .stream() .map(CompletableFuture::join) .toList(); 

anyOf:任意一个完成

CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3); all.thenRun(() -> System.out.println("all done")); 

⚠ 注意:allOf 不帮你收集结果,你需要自己 get(或 join)

List<Result> results = List.of(f1, f2, f3) .stream() .map(CompletableFuture::join) .toList(); 

anyOf:任意一个完成

CompletableFuture<Object> any = CompletableFuture.anyOf(f1, f2); any.thenAccept(r -> System.out.println("first = " + r)); 

常用于:

  • 多数据源兜底
  • 多节点竞速

五、异常处理:这是 CompletableFuture 的强项

1️⃣ exceptionally —— 兜底恢复

CompletableFuture .supplyAsync(() -> risky(), pool) .exceptionally(e -> { log.error("error", e); return defaultValue; }); 

2️⃣ handle —— 成功 / 失败都处理

future.handle((r, e) -> { if (e != null) { return fallback; } return r; }); 

一句工程经验:

CompletableFuture 的异常是“流的一部分”,不是打断流程。

六、超时控制(非常关键)

Java 9+ 推荐方式

future .orTimeout(2, TimeUnit.SECONDS) .exceptionally(e -> fallback); 

或者:

future .completeOnTimeout(fallback, 2, TimeUnit.SECONDS); 

比 Future.get(timeout) 的优势:

  • 不阻塞线程
  • 超时是异步语义的一部分

七、CompletableFuture + 线程池的最佳实践

✔ 1)明确线程池职责

  • IO 任务 → ioPool
  • CPU 任务 → cpuPool
  • 定时 → scheduledPool

CompletableFuture.supplyAsync(this::loadData, ioPool)

✔ 2)不要在 CompletableFuture 里 get()

// ❌ 反模式 future.thenApply(r -> anotherFuture.get()); 

✔ 3)异常必须收敛在链路末端

future .thenApply(...) .thenApply(...) .exceptionally(this::fallback); 

✔ 4)避免在 commonPool 跑重任务

ForkJoinPool 是共享资源,容易拖垮 JVM。

八、一个完整实战 Demo

补充知识点:

Java 的“高阶函数”到底是什么:Runnable / Callable 就是函数参数

CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(this::loadUser, ioPool); CompletableFuture<Order> orderFuture = CompletableFuture.supplyAsync(this::loadOrder, ioPool); CompletableFuture<UserInfo> result = userFuture .thenCombine(orderFuture, UserInfo::new) .orTimeout(2, TimeUnit.SECONDS) .exceptionally(e -> { log.error("timeout or error", e); return UserInfo.empty(); }); result.thenAccept(info -> render(info)); 

这个 Demo 覆盖了:

  • 并行
  • 合并
  • 超时
  • 异常
  • 自定义线程池

九、和前 9 篇的“闭环关系”

你现在拥有的是一套完整体系:

  • 线程池(1–5)
  • 任务提交与异常(6–7)
  • 可观测性(8)
  • 背压(9)
  • 异步编排(10) ← 收官

一句总结:

ThreadPoolExecutor 决定“系统能不能跑”,
CompletableFuture 决定“并发代码能不能写得优雅、可维护”。

十、全专栏终极总结

线程池是并发执行的基础设施背压决定系统是否稳定监控决定问题是否可见CompletableFuture 决定异步逻辑是否可维护并发不是“多开线程”,而是“正确组织任务关系”

到这里,已经是一个完整、工程级、的体系。

Read more

GitHub Agent HQ 全流程实战教程:从 Copilot Pro + 接入到代码库全生命周期管理(重构 + 测试 + 部署自动化 + 权限避坑)

GitHub Agent HQ 全流程实战教程:从 Copilot Pro + 接入到代码库全生命周期管理(重构 + 测试 + 部署自动化 + 权限避坑)

背景引入:AI 驱动的代码库全生命周期管理新范式 问题驱动 随着软件项目复杂度提升,开发者面临代码重构效率低、测试覆盖不足、部署流程繁琐、权限管理易疏漏等痛点。传统开发模式下,从代码编写到生产部署需跨多个工具链,上下文割裂导致协作成本高。GitHub Agent HQ 作为基于 Copilot Pro 的智能开发代理,通过大语言模型(LLM)深度理解代码库上下文,实现重构、测试、部署的全流程自动化,成为提升开发效率的核心工具。 技术趋势 2026 年,AI 辅助开发已从“代码补全”进化为“全流程代理”。GitHub Agent HQ 依托 Copilot Pro 的增强型 LLM 能力,结合 GitHub 原生生态,支持代码库深度索引、多步骤任务编排、工具链自动调用,是当前

By Ne0inhk
IntelliJ IDEA 接入 AI 编程助手(Copilot、DeepSeek、GPT-4o Mini)

IntelliJ IDEA 接入 AI 编程助手(Copilot、DeepSeek、GPT-4o Mini)

IntelliJ IDEA 接入 AI 编程助手(Copilot、DeepSeek、GPT-4o Mini) 📊 引言 近年来,AI 编程助手已成为开发者的高效工具,它们可以加速代码编写、优化代码结构,并提供智能提示。本文介绍如何在 IntelliJ IDEA 中集成 DeepSeek、GPT-4o Mini、GitHub Copilot,并探索 本地 AI 编程助手 方案,帮助开发者在不同场景下提升编程效率。 👨‍💻 1. GitHub Copilot 集成 Copilot 是由 GitHub 和 OpenAI 推出的 AI 代码补全工具,它可以根据上下文智能生成代码片段。 GitHub Copilot 免费版 vs 付费版对比。 功能免费版付费版代码补全每月

By Ne0inhk
【GitHub Copilot】Figma MCP还原设计稿生成前端代码

【GitHub Copilot】Figma MCP还原设计稿生成前端代码

这里写自定义目录标题 * Step1:让AI给你配置MCP * Step2:替换成自己的Figma密钥 * Step3:如何使用 Cursor+Figma MCP的教程已经很多了,由于我所在的公司采购的是GitHub Copilot,我研究了一下直接在vscode里利用GitHub Copilot接入Figma MCP进行设计稿还原代码,大获成功,这里分享我的步骤,希望能帮到你。 Step1:让AI给你配置MCP 在vscode中打开你的项目(我的例子是一个微信小程序),呼出github copilot对话框,模式选择Agent,模型建议Claude 3.7 Sonnet,提问: https://github.com/GLips/Figma-Context-MCP 如何配置能让你在vscode里使用这个mcp 之后跟着提示狂点下一步即可完成配置,如果有什么需要装的vscode插件它会自动帮你装,甚至自动生成了配置说明文档。 由于不能保证AI每次生成的答案都一致,这里附上我的运行结果作为参考,可以看到它在项目文件夹最外层建了一个.vscode文件夹,在sett

By Ne0inhk

AI写作助手来了!Qwen3-1.7B创意生成实测分享

AI写作助手来了!Qwen3-1.7B创意生成实测分享 导语:你有没有过这样的时刻——盯着空白文档半小时,标题还没想好;赶着交营销文案,却卡在第一句话;想写个有趣的故事开头,结果写了删、删了写……现在,一个装进笔记本电脑就能跑的AI写作助手真的来了。它不是动辄几十GB的庞然大物,而是一个仅1.7B参数、能在消费级显卡上流畅运行的轻量模型:Qwen3-1.7B。本文不讲参数、不聊架构,只用你每天都会遇到的真实写作场景,带你亲手试一试——它到底能不能帮你把“写不出来”变成“写得出来”,甚至“写得不错”。 1. 为什么是Qwen3-1.7B?一个能塞进你工作流的写作伙伴 很多人一听“大模型”,下意识想到的是需要多张A100、部署复杂、调用麻烦。但Qwen3-1.7B不一样。它的核心价值,不是和千亿模型比谁更“全能”,而是专注解决一个具体问题:在资源有限的前提下,提供稳定、可控、有风格的中文创意输出能力。 我们来拆解几个关键事实:

By Ne0inhk