全书概览
| 项目 | 内容 |
|---|---|
| 书稿 | 《Java 并发编程·性能诊断与事故》 |
| 篇数 | 50 篇(15 章 45 节 + 序、前言、目录 + 附录 A/B) |
| 领域 | 性能模型、基准与压测、诊断工具、锁故障、容量规划、虚拟线程、正确性验证、资源事故、可观测性、GC、容器化、工程规范 |
| 贯穿项目 | libraryd-conc —— 本卷把它压到队列满、锁热点、泄漏与配额不足的场景里 |
| 阅读方式 | 从目录篇 进入按顺序通读,或按症状跳读 |
| 主线版本 | JDK 25 LTS(Temurin 25.0.5+8)、Maven 3.9.12 |
| 关键依赖 | JCStress 0.16、JMH 1.37、JFR(JDK 内置)、colima 容器(Docker 29.5.2) |
| 上级专题 | 书稿专题 |
三卷分工
| 卷 | 书名 | 关注点 |
|---|---|---|
| 卷一 | 《Java 并发编程·线程与内存模型》 | 会写正确的并发代码 |
| 卷二 | 《Java 并发编程·JUC 源码与容器》 | 知道 JUC 为什么这样实现 |
| 卷三 | 《Java 并发编程·性能诊断与事故》 | 能压、能查、能救火 |
本卷不重复卷一的内存模型推导与卷二逐行读源码的内容;需要用到处会写「卷一第 N 章」或「卷二第 N 章」。
全书目录
前置
| 节 | 文章 | 核心内容 |
|---|---|---|
| — | 序:规则在压力下才见真章 | 三类失效、诊断闭环、本书口径 |
| — | 前言:实验环境、工具与数据口径 | 机器、JMH/JFR/JCStress、示例值与实测值的标注规则 |
| — | 目录与学习路径 | 三条路径、五部分、与卷一/卷二衔接 |
第一部分:性能模型、基准与诊断工具(第 1–3 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 1.1 | 1.1 Amdahl 与 USL:扩展性的天花板 | 串行比例、一致性延迟、公式的适用边界 |
| 1.2 | 1.2 上下文切换、调度延迟与 CPU 配额 | 切换成本、容器配额、线程数增加后的吞吐变化 |
| 1.3 | 1.3 吞吐、时延与并发的三角 | 平均 vs 分位、排队论直觉、尾延迟 |
| 2.1 | 2.1 JMH 的正确姿势 | @State 作用域、@Fork、Blackhole、误差列 |
| 2.2 | 2.2 微基准的陷阱 | 死代码消除、常量折叠、循环展开、预热 |
| 2.3 | 2.3 从微基准到系统压测 | 微基准能回答什么、不能回答什么 |
| 3.1 | 3.1 JFR 的 Monitor 事件 | jdk.JavaMonitorEnter、阈值、jfr view |
| 3.2 | 3.2 async-profiler 的锁与分配火焰图 | 安装、-e lock、-e alloc、读图方法 |
| 3.3 | 3.3 线程转储的读法 | Thread.print -l、BLOCKED、锁持有者、虚拟线程 |
第二部分:活性、容量与规模化(第 4–6 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 4.1 | 4.1 死锁的四个必要条件与检测 | 四个条件、findDeadlockedThreads、转储判读 |
| 4.2 | 4.2 活锁、饥饿与优先级反转 | 重试碰撞、写饥饿、优先级在 JVM 与 OS 两侧 |
| 4.3 | 4.3 锁顺序规范与超时兜底 | 全局层号、反向边检测、tryLock 超时 |
| 5.1 | 5.1 Little’s law 在池化中的应用 | L = λW、并发与时延的换算、余量系数 |
| 5.2 | 5.2 CPU 密集与 IO 密集的池大小 | N+1、N×(1+W/C)、实测校核 |
| 5.3 | 5.3 队列长度、拒绝率与降级 | 有界队列、CallerRuns、降级策略 |
| 6.1 | 6.1 十万/百万虚拟线程实测 | 创建耗时、堆占用、载体数、转储体积 |
| 6.2 | 6.2 pinning 的诊断与消除 | JDK 25 仍会 pin 的三类场景、JFR 阈值陷阱 |
| 6.3 | 6.3 连接池、ThreadLocal 与 MDC | 池仍受限、Semaphore 兜底、上下文传递 |
第三部分:模型对比、正确性测试与可见性(第 7–9 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 7.1 | 7.1 Reactor 的线程模型回顾 | 事件循环、非阻塞、背压 |
| 7.2 | 7.2 两种模型的取舍矩阵 | 团队、调试、生态、阻塞调用、尾延迟 |
| 7.3 | 7.3 混合栈的边界与调试 | 阻塞调用隔离、线程池边界、trace 传递 |
| 8.1 | 8.1 JCStress 的测试模型 | 状态、actor、arbiter、结果分级 |
| 8.2 | 8.2 Lincheck 的线性一致性检查 | 线性化点、场景生成、报告解读 |
| 8.3 | 8.3 竞态复现、最小化与回归 | 缩小状态、固定种子、CI 策略 |
| 9.1 | 9.1 过期读与无限循环 | JIT 提升、-Xint 对照、volatile 修复 |
| 9.2 | 9.2 安全发布失败的对象 | 构造逸出、部分初始化、final 冻结 |
| 9.3 | 9.3 从事故到 happens-before 归因 | 证据链、归因表、修复验证 |
第四部分:队列线程事故、锁边界与可观测性(第 10–12 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 10.1 | 10.1 队列堆积与 OOM | 无界队列、生产慢于消费、堆直方图 |
| 10.2 | 10.2 拒绝策略引发的雪崩 | 四种拒绝策略对照、重试放大、静默丢弃 |
| 10.3 | 10.3 线程泄漏与上下文类加载器 | 线程未退出、TCCL 持有、distinctTCCL 计数 |
| 11.1 | 11.1 数据库行锁与 Java 锁的叠加 | 锁顺序、事务边界、连接池占用 |
| 11.2 | 11.2 分布式锁的租约与续期 | 租约、时钟漂移、fencing token |
| 11.3 | 11.3 锁粒度、热点与拆分 | 分段、分片、无锁化,以及分位数的假象 |
| 12.1 | 12.1 线程与池的指标口径 | active/queue/completed/reject、getter 开销 |
| 12.2 | 12.2 阻塞点与调用链结合 | 阻塞耗时、线程到请求的映射、采样 |
| 12.3 | 12.3 告警阈值与容量水位 | 分位、饱和度、告警分级与去抖 |
第五部分:GC、容器与工程规范(第 13–15 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 13.1 | 13.1 分配速率、TLAB 与逃逸 | 分配速率、TLAB、标量替换 |
| 13.2 | 13.2 并发标记与业务线程 | 写屏障、标记线程占用、停顿 |
| 13.3 | 13.3 低延迟 GC 下的并发设计 | 分配控制、对象复用、伪共享 |
| 14.1 | 14.1 availableProcessors 与 CPU 配额 | 容器感知、ActiveProcessorCount、CFS 节流 |
| 14.2 | 14.2 内存限制、线程栈与容器 OOM | -Xss、MaxRAMPercentage、OOM 的几种类型 |
| 14.3 | 14.3 K8s 下的并发参数基线 | requests/limits、池大小、探针与退出 |
| 15.1 | 15.1 编码规范与静态检查 | 命名与可见性、锁顺序、禁止项、扫描规则 |
| 15.2 | 15.2 Code Review 清单 | 20 条评审问题、后果分级、三段式评论 |
| 15.3 | 15.3 libraryd 并发验收与压测报告 | 场景、指标、通过判据、遗留风险 |
附录
| 篇 | 文章 | 核心内容 |
|---|---|---|
| A | 附录 A 诊断命令速查 | 线程、JFR、内存、CPU 与容器 cgroup 的命令与判读 |
| B | 附录 B JCStress/JMH/压测模板 | 三个可复制、可运行的模板 |
三条阅读路径
| 路径 | 适合谁 | 怎么走 |
|---|---|---|
| 顺序通读 | 想建立完整的诊断能力 | 1.1 → 15.3,约 35 小时 |
| 症状驱动 | 手上正有一个故障 | 先看目录篇 的「症状 → 章节」对照表 |
| 值班查表 | 正在处理线上问题 | 附录 A 命令 + 第 12 章指标口径 + 4.3 锁顺序 |
相关专题
- 《Java 并发编程·线程与内存模型》 —— 本卷的前置,讲规则本身
- 《Java 并发编程·JUC 源码与容器》 —— 本卷的前置,讲实现为什么这样写
- 《Java 虚拟机原理与性能调优》 —— GC 与内存参数的系统讲解
- 书稿专题 —— 全部电子书