AQS 并发包原理
ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock……它们底层都依赖 AQS。理解 AQS,就理解了 Java 并发工具的设计灵魂。
一、AQS 是什么
- 1.1 AbstractQueuedSynchronizer——基于 FIFO 等待队列的同步框架
- 1.2 设计模式:模板方法模式
- 1.3 核心三要素:state 状态、CLH 队列、Condition 条件队列
二、state——同步状态的原子管理
- 2.1
volatile int state+ CAS 的原子操作 - 2.2
getState()/setState()/compareAndSetState() - 2.3 state 在不同工具中的含义——ReentrantLock(重入次数)、Semaphore(许可数)
三、CLH 队列——线程排队机制
- 3.1 CLH 锁的原始设计——自旋等待前驱节点
- 3.2 AQS 中的变体——阻塞而非自旋
- 3.3 Node 节点结构:
prev/next/waitStatus/thread - 3.4 waitStatus 的 5 种状态(CANCELLED / SIGNAL / CONDITION / PROPAGATE)
- 3.5 入队 enq() 与出队 setHead() 流程
四、独占模式——以 ReentrantLock 为例
- 4.1
acquire()模板方法流程 - 4.2
tryAcquire()——公平锁 vs 非公平锁的实现差异 - 4.3
addWaiter()入队 - 4.4
acquireQueued()——阻塞等待唤醒 - 4.5
release()释放与唤醒后继节点
五、共享模式——以 Semaphore / CountDownLatch 为例
- 5.1
acquireShared()模板方法 - 5.2
tryAcquireShared()——共享获取的判断逻辑 - 5.3
doReleaseShared()——setHeadAndPropagate 传播机制 - 5.4 传播的意义——一个释放可能唤醒多个等待线程
六、Condition 条件队列
- 6.1 Condition 与 Object 的 wait/notify 对比
- 6.2
await()——释放锁 → 进入条件队列 → 阻塞 - 6.3
signal()——从条件队列转移到同步队列 - 6.4 ConditionObject 数据结构
七、手写一个简易锁——加深理解
- 7.1 基于 AQS 实现不可重入的互斥锁
- 7.2 基于 AQS 实现可重入锁
- 7.3 测试代码及结果
八、总结
- AQS 的设计精华——模板方法 + CAS + CLH
- 什么时候需要基于 AQS 自定义同步器
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 谜思录!