Java 并发编程 专栏导览
专栏定位
本专栏聚焦 Java 并发编程的底层原理与工程实践——从硬件层面的 CPU 缓存一致性协议(MESI)到 JVM 层面的 Java 内存模型(JMM),从操作系统层面的线程调度到 JDK 层面的 synchronized、AQS、ConcurrentHashMap。并发编程是 Java 工程师进阶的分水岭——理解它不仅需要掌握 API 的使用方式,更需要理解”为什么要这样设计”以及”不这样做会出什么问题”。
本专栏覆盖 JDK 8 到 JDK 21 的并发体系演进,从底层硬件模型出发,逐层向上推导,最终落地到生产环境的高并发场景实战。
目标读者
- 希望从”会用 synchronized”进阶到”理解锁升级的每一步”的中高级工程师
- 需要设计高并发系统、排查并发 Bug(死锁、数据竞争、内存可见性问题)的后端开发者
- 对 JDK 并发包源码感兴趣的技术爱好者
专栏目录
📂 线程安全问题/
| 序号 | 标题 | 核心内容 |
|---|---|---|
| 01 | 01 并发编程的硬件基础——CPU 缓存、MESI 与内存屏障 | 多核 CPU 架构、L1/L2/L3 缓存层次、缓存行(Cache Line)、MESI 协议的四种状态、Store Buffer 与 Invalidate Queue、内存屏障(LoadLoad/StoreStore/LoadStore/StoreLoad)的硬件语义 |
| 02 | 02 Java 内存模型(JMM)——happens-before 与可见性保证 | JMM 的抽象模型(主内存/工作内存)、happens-before 八大规则、as-if-serial 与指令重排序、JMM 如何映射到硬件内存屏障 |
📂 volatile与内置锁/
| 序号 | 标题 | 核心内容 |
|---|---|---|
| 03 | 03 volatile 的实现原理——内存屏障与禁止重排序 | volatile 的可见性保证、volatile 写的 StoreStore + StoreLoad 屏障、volatile 读的 LoadLoad + LoadStore 屏障、volatile 的非原子性、DCL 单例中 volatile 的必要性 |
| 04 | 04 synchronized 的锁升级——偏向锁、轻量级锁与重量级锁 | 对象头 Mark Word 的位布局、偏向锁的批量重偏向与批量撤销、轻量级锁的 CAS 自旋、重量级锁的 Monitor 机制(EntryList/WaitSet)、JDK 15 废弃偏向锁的原因 |
| 05 | 05 CAS 与原子类——Unsafe、AtomicInteger 到 LongAdder 的演进 | Compare-And-Swap 的 CPU 指令(CMPXCHG)、ABA 问题与 AtomicStampedReference、AtomicInteger/AtomicLong 的实现、LongAdder 的分段思想(Cell 数组 + base)、@Contended 防止伪共享 |
📂 JUC工具/
| 序号 | 标题 | 核心内容 |
|---|---|---|
| 06 | 06 AQS 框架——AbstractQueuedSynchronizer 的设计与实现 | state 变量的语义复用、CLH 队列变体(双向链表)、独占模式(acquire/release)、共享模式(acquireShared/releaseShared)、ConditionObject 的等待队列、AQS 的模板方法模式 |
| 07 | 07 ReentrantLock 深度剖析——公平锁、非公平锁与可中断 | ReentrantLock 基于 AQS 的实现、公平锁的 hasQueuedPredecessors 检查、非公平锁的插队策略、lockInterruptibly 的中断响应、tryLock 的超时机制、与 synchronized 的对比选型 |
| 08 | 08 读写锁与 StampedLock——从 ReentrantReadWriteLock 到乐观读 | 读写锁的 state 高低 16 位分割、写锁饥饿问题、锁降级(写→读)的正确姿势、StampedLock 的乐观读(tryOptimisticRead)、StampedLock 的状态机与性能优势 |
| 09 | 09 并发容器(上)——ConcurrentHashMap 从 JDK 7 到 JDK 8 的重构 | JDK 7 的 Segment 分段锁(16 段)、JDK 8 的 CAS + synchronized(Node 数组 + 链表/红黑树)、扩容的并发协助(transfer)、size() 的 CounterCell 实现、computeIfAbsent 的死锁陷阱 |
| 10 | 10 并发容器(下)——CopyOnWriteArrayList、BlockingQueue 家族 | CopyOnWriteArrayList 的写时复制语义与适用场景、ArrayBlockingQueue 的双锁设计、LinkedBlockingQueue 的分离锁、SynchronousQueue 的直接传递、DelayQueue 的延迟调度、PriorityBlockingQueue 的堆排序 |
| 13 | 13 CompletableFuture 与异步编程模型 | Future 的局限性、CompletableFuture 的链式编排(thenApply/thenCompose/thenCombine)、异常处理(exceptionally/handle)、allOf/anyOf 的聚合、自定义线程池的最佳实践 |
| 14 | 14 并发工具类——CountDownLatch、CyclicBarrier、Semaphore、Phaser | CountDownLatch 的一次性门闩(AQS 共享模式)、CyclicBarrier 的可循环屏障(ReentrantLock + Condition)、Semaphore 的信号量限流、Phaser 的分阶段同步、Exchanger 的线程间数据交换 |
| 15 | 15 ThreadLocal 的实现原理与内存泄漏 | Thread.threadLocals 的 ThreadLocalMap 结构、开放寻址法解决冲突、弱引用 Entry 的设计、内存泄漏的根因(Entry.value 强引用)、expungeStaleEntry 的清理机制、InheritableThreadLocal 与 TransmittableThreadLocal |
| 16 | 16 JDK 21 虚拟线程——Project Loom 的协程实现 | 平台线程 vs 虚拟线程、Continuation 的挂起与恢复、Carrier Thread 与 ForkJoinPool 的调度、Pinning 问题(synchronized 导致载体线程不释放)、虚拟线程的适用场景与限制 |
📂 线程池/
| 序号 | 标题 | 核心内容 |
|---|---|---|
| 11 | 11 线程池(上)——ThreadPoolExecutor 的七大参数与执行流程 | 核心线程数/最大线程数/存活时间/工作队列/线程工厂/拒绝策略的设计意图、execute 的三步决策(核心线程→队列→最大线程)、Worker 的 AQS 实现、shutdown vs shutdownNow 的区别 |
| 12 | 12 线程池(下)——ForkJoinPool 与工作窃取算法 | 分治思想与 RecursiveTask/RecursiveAction、工作窃取(Work-Stealing)算法的双端队列、ForkJoinPool 的 commonPool、parallelStream 的线程池陷阱、CompletableFuture 的默认线程池 |
📌 实战总结(根目录)
| 序号 | 标题 | 核心内容 |
|---|---|---|
| 17 | 17 实战——高并发场景下的锁优化与无锁编程 | 减小锁粒度、锁分离(读写分离)、无锁数据结构(Disruptor RingBuffer)、CAS 重试的退避策略、分布式环境下的并发控制(Redis 分布式锁与数据库乐观锁)、性能压测方法论(JMH) |
推荐阅读路径
基础路径(理解并发为什么难):01 → 02 → 03 → 04 → 05
JDK 并发包深入路径:06 → 07 → 08 → 09 → 10 → 14
线程池与异步路径:11 → 12 → 13
实战与新特性路径:15 → 16 → 17
前置知识
- Java 基础语法和多线程基本使用(Thread、Runnable)
- 建议同步阅读 JVM 专栏中的对象内存布局(理解 Mark Word)和 JIT 编译(理解锁消除/锁粗化)
关联专栏
- JVM 专栏:对象头 Mark Word、锁升级、JIT 锁消除等核心知识
- Linux 进程管理:Java 线程与 Linux 线程的 1:1 映射,futex 系统调用实现锁
- Go 并发编程:对比 synchronized vs Go Mutex、BlockingQueue vs Channel
- 分布式锁:从单机锁扩展到分布式环境下的锁机制
- Redis 分布式锁:Redis 实现分布式锁的实践