Java 进阶 01:JUC、线程池、CompletableFuture 与异步组合实战
写给高级工程师:happens-before 直觉、Lock 与原子类、ExecutorService 参数含义、超时/取消/组合异步;常见踩坑与背压入门。
- Java
- 并发
- JUC
- 异步
本篇目标:能画出 happens-before 关系;能配置
ThreadPoolExecutor而不是只会Executors.newFixedThreadPool;能用CompletableFuture组合异步并在全链路加超时;知道 MDC/trace id 在异步里会丢。
1. 知识点:JMM 与 happens-before(最小集)#
- 程序次序:同线程内语句顺序(在不重排破坏 as-if-serial 前提下)。
- 监视器锁:解锁 happens-before 后续加锁同锁的其他线程。
volatile写 happens-before 后续 volatile 读。Thread.starthappens-before 新线程任何动作;join 返回 happens-before 后续。
学以致用:解释「未同步读共享字段可能永远看到 false」的双检锁为何需要 volatile 或静态 holder。
2. 知识点:ReentrantLock vs synchronized#
| 能力 | synchronized | ReentrantLock |
|---|---|---|
| 可中断等待 | 否 | lockInterruptibly |
| 尝试超时 | 否 | tryLock |
| 条件队列 | wait/notify | Condition |
3. 知识点:ThreadPoolExecutor 七个参数#
new ThreadPoolExecutor(
4, // corePoolSize
8, // maximumPoolSize
60L, TimeUnit.SECONDS, // keepAliveTime
new ArrayBlockingQueue<>(1000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy()
);必答:任务进来先扩 core → 入队 → 扩到 max → 触发拒绝策略。无界队列 + 固定 max 会让 max 形同虚设。
4. 知识点:CompletableFuture#
| 方法 | 含义 |
|---|---|
supplyAsync | 有返回值异步 |
thenApply | 转换 |
thenCompose | 扁平化异步 |
thenCombine | 合并两个独立异步 |
orTimeout / completeOnTimeout | Java 9+ 超时 |
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> slowA(), pool);
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> slowB(), pool);
String out = a.thenCombine(b, (x, y) -> x + y).orTimeout(2, TimeUnit.SECONDS).join();坑:业务线程池与 IO 线程池隔离;异常用 exceptionally/handle 统一映射;MDC 需手动传递或用框架封装。
5. 知识点:Semaphore 限流#
Semaphore sem = new Semaphore(10);
sem.acquire();
try {
callRemote();
} finally {
sem.release();
}6. 知识点:ConcurrentHashMap.computeIfAbsent 提醒#
长耗时计算禁止在 computeIfAbsent 里做且锁粒度可能阻塞其他桶——热点 key 下会放大停顿。复杂场景考虑分段加载或异步刷新。
7. Lab#
并行调用三个模拟延迟服务(Thread.sleep),合并 JSON 字段;全链路 2s 超时,超时返回降级对象;统计超时次数用 LongAdder。
8. 自测清单#
- 说出两条 happens-before 规则并举例。
CallerRunsPolicy对系统负载意味着什么?thenCompose与thenApply区别?- 为何异步链路里日志找不到 traceId?
下一篇:JVM 与 GC。
相关阅读
基于内容相似度 + 标签/系列加权
- 2 分钟Java 从基础到精通(初级 · 高级 · 专家路线)
Java 基础 03:异常体系、try-with-resources、IO/NIO.2 入门与并发初探
初级收尾篇:受检/非受检异常取舍、异常链与日志;现代 IO 用法;线程与 synchronized 的最小正确用法,为进阶 JUC 铺路。
- Java
- 异常
- IO
- 2 分钟Java 从基础到精通(初级 · 高级 · 专家路线)
Java 基础 02:面向对象、集合框架与泛型(正确用上接口与算法复杂度)
初级必读:类/接口/抽象的分工、equals 与 hashCode 契约、List/Set/Map 选型、迭代与并发修改;泛型如何避免强制转换地狱。
- Java
- 集合
- 泛型
- 2 分钟Java 从基础到精通(初级 · 高级 · 专家路线)
Java 路线 00:从初级到专家的三层能力模型、学习顺序与全系列索引
面向初级、高级与资深/专家 Java 工程师的分层路线:每层该学什么、如何验收、与本系列各篇的对应关系;附统一练习模板与进阶节奏。
- Java
- 学习路线
- 方法论
- 2 分钟Java 从基础到精通(初级 · 高级 · 专家路线)
Java 基础 01:平台、JDK、字节码与可维护的最小项目骨架
写给初级工程师:JVM/JRE/JDK 分工、源码到字节码的路径、classpath 与模块的基础心智;用 Maven 或 Gradle 搭一个最小可测试骨架。
- Java
- JVM
- 基础