全书概览
| 项目 | 内容 |
|---|---|
| 书稿 | 《Java 并发编程·JUC 源码与容器》 |
| 篇数 | 50 篇(15 章 45 节 + 序、前言、目录 + 附录 A/B) |
| 领域 | 队列同步器、显式锁、并发容器、阻塞队列、原子类、VarHandle、无锁结构、执行器、异步编排 |
| 贯穿项目 | libraryd-conc —— 本卷拆开 LockedLoanService 与 PooledLoanService 看实现,新增 MapBackedStockCache |
| 阅读方式 | 从目录篇 进入按顺序通读,或按症状跳读 |
| 主线版本 | JDK 25 LTS(Temurin 25.0.5+8)、Maven 3.9.12 |
| 关键依赖 | JCStress 0.16、JMH 1.37、JUnit Jupiter 5.14.4 |
| 上级专题 | 书稿专题 |
三卷分工
| 卷 | 书名 | 关注点 |
|---|---|---|
| 卷一 | 《Java 并发编程·线程与内存模型》 | 会写正确的并发代码 |
| 卷二 | 《Java 并发编程·JUC 源码与容器》 | 知道 JUC 为什么这样实现 |
| 卷三 | 《Java 并发编程·性能诊断与事故》 | 能压、能查、能救火 |
本卷不重复卷一的 JMM 推导与基本用法,也不做卷三的压测与线上诊断;遇到这些内容会写「卷一第 N 章已讲」或「卷三第 N 章展开」。
全书目录
前置
| 节 | 文章 | 核心内容 |
|---|---|---|
| — | 序:为什么要读 JUC 源码 | 读源码的三层收益、版本差异、三卷边界、源码标注方式 |
| — | 前言:源码版本、工具与约定 | src.zip 获取、包结构、javap、JMH/JCStress、JDK 25 差异清单 |
| — | 目录与学习路径 | 三条路径、十五章依赖、症状对照表、六个误区 |
第一部分:队列同步器与显式锁(第 1–4 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 1.1 | 1.1 AQS 的 state 与 CLH 变体队列 | state、Node 四字段、三个状态位、头尾指针、为什么用 CLH 变体 |
| 1.2 | 1.2 独占模式的 acquire/release | acquire 大循环、tryInitializeHead、signalNext、cancelAcquire/cleanQueue |
| 1.3 | 1.3 共享模式与传播机制 | tryAcquireShared 三种返回值、SharedNode、signalNextIfShared |
| 2.1 | 2.1 ReentrantLock 的公平与非公平 | initialTryLock 插队、hasQueuedThreads/hasQueuedPredecessors、吞吐差异 |
| 2.2 | 2.2 Condition 的条件队列 | ConditionObject、await/signal、nextWaiter、节点转移 |
| 2.3 | 2.3 锁的中断、超时与可重入 | acquire 返回语义、tryLock(timeout)、重入计数边界 |
| 3.1 | 3.1 ReentrantReadWriteLock 的 state 拆分 | AbstractQueuedLongSynchronizer、高低 32 位、HoldCounter |
| 3.2 | 3.2 锁降级与写锁饥饿 | 降级顺序、signalNextIfShared 连续唤醒、非公平下的写饥饿 |
| 3.3 | 3.3 StampedLock 的乐观读 | 版本戳、tryOptimisticRead、validate、不可重入 |
| 4.1 | 4.1 Semaphore 与许可模型 | 共享模式、公平性、reducePermits/drainPermits |
| 4.2 | 4.2 CountDownLatch、CyclicBarrier、Phaser | 一次性 vs 可重用 vs 分阶段、Phaser 的 long state |
| 4.3 | 4.3 Exchanger 与同步器组合 | Slot/Participant、配对与超时、组合死锁 |
第二部分:并发容器与阻塞队列(第 5–7 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 5.1 | 5.1 ConcurrentHashMap 的节点结构 | Node/TreeBin/ForwardingNode、sizeCtl 多重语义、桶状态 |
| 5.2 | 5.2 put/get 的并发路径与 size 统计 | 无锁读、桶首 CAS、helpTransfer、addCount、sumCount |
| 5.3 | 5.3 弱一致迭代与复合操作 | 迭代器语义、Traverser、compute/merge 的原子性边界 |
| 6.1 | 6.1 CopyOnWriteArrayList/Set | 写时复制路径、读为什么无锁、迭代器不抛 CME、内存代价 |
| 6.2 | 6.2 ConcurrentSkipListMap | Index 的 down/right、无 level 字段、CAS 插入、有序并发 |
| 6.3 | 6.3 并发集合选型矩阵 | 有序性、读写成败、迭代语义、内存放大 |
| 7.1 | 7.1 ArrayBlockingQueue 与 LinkedBlockingQueue | 单锁 vs 双锁、notEmpty/notFull、容量语义 |
| 7.2 | 7.2 SynchronousQueue、Priority、Delay | Transferer 复用 LinkedTransferQueue、堆与 allocationSpinLock、leader 交接 |
| 7.3 | 7.3 队列的锁粒度、吞吐与内存 | 锁拆分、节点开销、伪共享 |
第三部分:原子类与无锁结构(第 8–10 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 8.1 | 8.1 AtomicInteger 家族的 CAS 路径 | 为什么仍走 jdk.internal.misc.Unsafe、weakCompareAndSet、字段更新器 |
| 8.2 | 8.2 LongAdder 的 Cell 分片 | Cell 的 @Contended 与 VALUE 句柄、base + cells、sum() 的弱一致 |
| 8.3 | 8.3 Striped64 与高并发计数设计 | 探针哈希、cellsBusy、longAccumulate 的四条分支 |
| 9.1 | 9.1 VarHandle 的访问模式 | 五种访问模式、getAcquire/setRelease、compareAndSet |
| 9.2 | 9.2 内存屏障与 acquire/release | 部分屏障、fullFence、与 volatile 的关系 |
| 9.3 | 9.3 用 VarHandle 替换 Unsafe | 字段句柄、数组句柄、MethodHandles.lookup、迁移对照 |
| 10.1 | 10.1 无锁栈与 Michael-Scott 队列 | Treiber 栈、MS 队列的 head/tail |
| 10.2 | 10.2 ABA 与内存回收 | 版本戳、AtomicMarkableReference、Hazard Pointer 思路 |
| 10.3 | 10.3 无锁 vs 有锁实测 | 竞争度、CAS 失败率、吞吐与尾延迟 |
第四部分:执行器与异步编排(第 11–13 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 11.1 | 11.1 ctl 与 Worker 生命周期 | 高 3 位状态、低 29 位线程数、Worker 继承 AQS |
| 11.2 | 11.2 addWorker、runWorker 与退出 | 双重检查、beforeExecute、processWorkerExit |
| 11.3 | 11.3 DelayedWorkQueue | 堆、leader、available 条件 |
| 12.1 | 12.1 工作窃取队列与任务扫描 | WorkQueue 数组、base/top、scan |
| 12.2 | 12.2 双向队列与 steal 竞争 | poll 与 steal 的方向、casSlotToNull |
| 12.3 | 12.3 并行流的拆分策略 | Spliterator、trySplit、AbstractTask |
| 13.1 | 13.1 CompletableFuture 的依赖栈 | Completion 链、UniApply、BiRelay |
| 13.2 | 13.2 异步任务的执行器选择 | ASYNC/NESTED/SYNC、commonPool 默认 |
| 13.3 | 13.3 异常传播与取消 | AltResult、encodeThrowable、cancel 语义 |
第五部分:组合模式与误用清单(第 14–15 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 14.1 | 14.1 超时、重试与熔断的并发实现 | 截止时间、退避、状态机 |
| 14.2 | 14.2 批量聚合与背压 | 批量窗口、有界队列、拒绝 |
| 14.3 | 14.3 并发限流与信号量池 | 许可、公平、泄漏检测 |
| 15.1 | 15.1 双重检查锁定的正确写法 | 为什么需要 volatile、静态持有者 |
| 15.2 | 15.2 线程安全类的组合不安全 | 原子操作 ≠ 原子组合、compute 的边界 |
| 15.3 | 15.3 JUC 误用清单与 Code Review | 20 条检查项、按后果分级 |
附录
| 篇 | 文章 | 核心内容 |
|---|---|---|
| A | 附录 A JUC 类图与选型表 | 锁、队列、容器、原子类、执行器的分类图与选型表 |
| B | 附录 B 源码阅读路径与调试技巧 | 从哪个类读起、javap、断点、JFR |
三条阅读路径
| 路径 | 适合谁 | 怎么走 |
|---|---|---|
| 顺序通读 | 想系统补齐 JUC、准备面试 | 1.1 → 15.3,约 40 小时 |
| 症状驱动 | 手上有具体问题 | 先看目录篇 的「症状 → 章节」对照表 |
| 按类查阅 | 正在改某段代码 | 按类名跳到对应章节,配合附录 A |
相关专题
- 《Java 并发编程·线程与内存模型》 —— 本卷的前置,讲怎么写得对
- 《Java 虚拟机原理与性能调优》 —— GC 与并发问题经常纠缠在一起
- 《Java 高级编程》 —— 第 4–6 章给的是结论,本卷给的是实现与取舍
- 书稿专题 —— 全部电子书