Java 并发编程专题:线程、锁、JMM、CAS、AQS、线程池与虚拟线程
并发知识点多而杂,零散刷题容易「会背不会用」。这张学习地图把并发模块分成四组主题,标出依赖关系与推荐顺序,并让每个主题回答同一个问题:它到底解决什么。
主题分组
第一组:线程基础
- 线程与生命周期:线程有哪些状态、何时切换——一切并发问题分析的前提。
- 线程安全与死锁:先定义「什么叫安全」,再谈死锁的成因与排查。
第二组:内存模型与锁
- JMM(Java 内存模型):解释为什么一个线程的修改另一个线程可能看不到——可见性、有序性、原子性三大问题的总纲。
- volatile:轻量解决可见性与指令重排,但不解决原子性。
- synchronized 与锁体系:一站式解决互斥,顺带通过 Monitor 机制保证可见性;延伸到 ReentrantLock、读写锁。
- 乐观锁与悲观锁:应对并发冲突的两种哲学——先干活再补救,还是先加锁再干活。
第三组:无锁与同步器
- CAS:用一条 CPU 原子指令替代加锁,是无锁编程的硬件基石,代价是 ABA 问题与自旋开销。
- Atomic 原子类:CAS 的封装,解决计数器、引用更新这类单变量并发问题。
- AQS:把「抢不到锁就排队」抽象成模板,是 Java 锁与同步工具的公共底座。
第四组:工程实践
- 并发容器与阻塞队列:开箱即用的线程安全数据结构。
- 线程池:把线程从「一次性消耗品」变成「可管理资源」。
- ThreadLocal:解决线程间的数据隔离,代价是泄漏与脏数据风险。
- CompletableFuture:把异步任务从「提交后干等」升级为可编排的流水线。
- 虚拟线程(Java 21):用极低成本支撑海量 IO 并发,改写了不少线程池时代的经验。
依赖关系
主线是严格递进的:不懂线程状态,就看不懂锁的阻塞与唤醒;不懂 JMM 的可见性,就不理解 volatile 为什么存在;没有 CAS 概念,AQS 的 state 更新就是黑盒;不理解 AQS,ReentrantLock、Semaphore、CountDownLatch 就得各背一遍,而不是一通百通。线程池站在所有基础之上——任务队列、拒绝策略、线程生命周期全都要调用前面的知识。这就是为什么跳步学并发,学到最后都是空中楼阁。
推荐学习顺序
- 线程基础:状态转换、中断语义、死锁四要素。
- JMM 与 volatile:建立「内存可见性」这个核心直觉。
- synchronized 与锁:Monitor 原理、锁升级,再到 ReentrantLock。
- CAS 与原子类:理解无锁思路及其边界。
- AQS:打通锁与同步工具的底层实现。
- 并发容器与同步工具类:站在 AQS 上俯视它们。
- 线程池:核心参数、执行流程、拒绝策略与生产调优。
- ThreadLocal 与 CompletableFuture:业务并发最常用的两大件。
- 虚拟线程:了解新范式及其适用边界。
一句话索引
| 主题 | 它解决什么问题 |
|---|---|
| 线程生命周期 | 线程从哪来、何时消亡、中间卡在哪 |
| 死锁 | 多锁交叉等待导致永久阻塞,如何排查与预防 |
| JMM | 多线程共享变量时「看不看得见、会不会乱序」 |
| volatile | 不加锁的轻量可见性保证 |
| synchronized | 互斥与可见性的一站式关键字 |
| CAS | 不加锁也能安全更新单个变量 |
| AQS | 所有同步器共享的排队与唤醒框架 |
| 并发容器 | 免去手动加锁的线程安全集合 |
| 线程池 | 线程复用、并发度控制与任务调度 |
| ThreadLocal | 每个线程独享一份的私有变量 |
| CompletableFuture | 异步任务的编排、组合与异常处理 |
| 虚拟线程 | 海量并发下的廉价线程 |
走完这条路线后,回去做一次自检:能否不看资料讲清「volatile 为什么不保证原子性」「AQS 的 state 在 ReentrantLock 和 CountDownLatch 里分别代表什么」「线程池为什么先入队再扩线程」。讲得清楚,地图才算真正走完。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dai Wei!
评论

