本文主要分析非公平锁的逻辑,其逻辑本身并不复杂,但考虑到AQS中的逻辑重用和队列维护的基础结构会影响到后续对其他相关子类的理解,所以描述的会比较啰嗦~
ReentrantLock的使用很简单,就像这样:
ReentrantLock lock = new ReentrantLock();
lock.lock();
//do something
lock.unlock();
先看ReentrantLock的构造方法:
private final Sync sync;
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
ReentrantLock主要提供两个构造函数对成员变量sync进行赋值,Sync是一个静态内部抽象类,继承自AbstractQueuedSynchronizer(AQS)。
Sync有两个子类,FairSync和NonfairSync,分别代表公平锁的实现和非公平锁的实现,这两个类也是ReentrantLock的静态内部类。无参构造函数创建的是NonfairSync,也就是非公平锁。我们接着来看看NonfairSync的继承关系:
从继承关系图中可以看出来,AQS还继承了一个AbstractOwnableSynchronizer类,这个类是一个抽象类,其提供了一个Thread类型的exclusiveOwnerThread属性。这个属性用于保存当前持有锁的线程,可以用于判断锁的重入,这在下面的源码中也会有所体现。
我们回到ReentrantLock的加锁逻辑,lock()方法:
public void lock() {
sync.lock();
}
lock()方法调用的就是sync.lock()方法,本例中我们使用默认构造函数生成的是NonfairSync,所以先来看看NonfairSync类:
static final class NonfairSync extends Sync {
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
可以看到NonfairSync类非常简单,因为其主要逻辑都在父类中。所以lock()方法看起来非常简单,就是一个if-else。我们先看if的条件,也就是:
compareAndSetState(0, 1)
这个方法定义在父类AQS中:
protected final boolean compareAndSetState(int expect, int update) {