整体结构
- ReentrantLock implements Lock
- ReentrantLock 内引用 Sync
- Sync extends AbstractQueuedSynchronizer
- AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer
- Sync 有两个子类 FairSync 和 NonfairSync
实现原理
实现一把具有阻塞和唤醒功能的锁,需要几个核心要素:
- 需要一个state变量,标记锁的状态。state变量至少两个值,对state变量的操作,要确保线程安全,也就是会用到 CAS
- 需要记录当前是哪个线程持有锁
- 需要底层支持对一个线程进行阻塞或唤醒操作
- 需要一个队列维护所有阻塞的队列。这个队列必须是线程安全的无锁队列,也需要用到 CAS
队列同步器
队列同步器 AbstractQueuedSynchronizer,是用来构建锁或者其他同步组 件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO双向队列来完成资源获 取线程的排队工作,并发包的作者(Doug Lea)期望它能够成为实现大部分同步需求的基础。
AQS 本质上是一个 FIFO 的双向队列,线程被包装成结点的形式,基于自旋机制在队列中等待获取资源(这里的资源可以简单理解为对象锁)。AQS 在设计上实现了两类队列,即 同步队列 和 条件队列 ,其中同步队列服务于线程阻塞等待获取资源,而条件队列则服务于线程因某个条件不满足而进入等待状态。条件队列中的线程实际上已经获取到了资源,但是没有能够继续执行下去的条件,所以被打入条件队列并释放持有的资源,以让渡其它线程执行,如果未来某个时刻条件得以满足,则该线程会被从条件队列转移到同步队列,继续参与竞争资源,以继续向下执行。