整体概况
ReentrantLock实现了Lock接口,基于AbstractQueuedSynchronizer(AQS)实现了可重入独占锁,通过私有内部类Sync继承AbstractQueuedSynchronizer,分别实现了Sync的两个子类FairSync和NonfairSync,对应ReentrantLock的公平锁和非公平锁。ReentrantLock的加锁调用的是Sync的lock方法,解锁过程调用的是Sync的tryRelease方法。ReentrantLock的代码结构如下图所示:
ReentrantLock代码结构从上图可以看出,ReentrantLock代码大致可以分为4部分,分别是Sync部分、NonfairSync、FairSync和其他直接使用AbstractQueuedSynchronizer代码部分。
加锁过程
Sync
abstract void lock(),抽象方法,分别在子类FairSync和NonfairSync去实现。
final boolean nonfairTryAcquire(int acquires),抢占方式获取锁,如下图所示,当锁没被占用时,直接通过compareAndSetState尝试获取锁,不管当前队列中是否有其他对象在等待,此处体现出抢占式,当锁被占用时,如果占有锁的线程是当前线程,则将锁的状态变量加1,然后获取锁,此处体现出了重入性;如果不是当前线程占有锁,则此次获取锁失败,返回false。
nonfairTryAcquire源码protected final boolean tryRelease(int releases),尝试释放锁。由于此处实现的锁是可重入的,所以释放锁的时候,先将锁状态变量减1。如果减1之后,锁状态变量变为0,则锁被完全释放,并且将锁的所属线程设置为null。此处不会有线程安全问题。具体代码如下图所示。
tryRelease源码
NonfairSync
非公平锁的实现,Sync的子类,加锁过程调用的Sync的nonfairTryAcquire。解锁过程调用Sync的tryRelease,源码如下图所示。
NonfairSync源码FairSync
公平锁的实现,Sync的子类,获取锁时,如果当前锁没有被占用,则会查看等待队列中是否有其他对象在排队等待锁。如果有其他对象在排队的话,则本次获取锁失败,自己进入等待队列。此处体现出了公平性。公平锁和非公平锁就在锁没有被占用时获取锁的行为不同,其他都一毛一样。解锁过程同样调用Sync的tryRelease。FairSync的代码如下图所示。
FairSync源码ReentrantLock其他部分源码
ReentrantLock其他部分代码很简单,都是间接调用AQS的方法,如getOwner、hasQueuedThreads、hasQueuedThread和getQueueLength等等,如下图所示。
ReentrantLock其他源码
网友评论