开篇
写完synchronized自然而然就必须分析一下java体系当中的另外一个锁ReentrantLock,相比synchronized的jvm层实现,ReentrantLock是jdk层面的实现。
整个系列会分成3个部分进行讲解,分别是ReentrantLock本身的类关系,公平锁FairSync、非公平锁NonfairSync。
之所以把ReentrantLock本身的类关系单独拿出来讲,是因为我觉得理解了ReentrantLock内部的几个类能够更加清晰理解锁的调用过程。
java源码 - ReentrantLock
java源码 - ReentrantLock之FairSync
java源码 - ReentrantLock之NonfairSync
java源码 - ReentrantLock图解加锁过程
类关系图
说明:
- FairSync继承自Sync,Sync继承自AbstractQueuedSynchronizer。
说明:
- NonfairSync继承自Sync,Sync继承自AbstractQueuedSynchronizer。
源码层面分析
从源码可以看出几个比较重要的点:
- Sync继承自AbstractQueuedSynchronizer
- NonfairSync和FairSync继承自Sync
- ReentrantLock的变量sync保存NonfairSync和FairSync,都继承自Sync。
- ReentrantLock的构造函数创建NonfairSync和FairSync对象赋值给sync
- ReentrantLock的lock()和unlock()调用的是sync的lock()和unlock()方法
public class ReentrantLock implements Lock, java.io.Serializable {
// 保存公平锁对象或者非公平锁对象
private final Sync sync;
// 抽象类Sync
abstract static class Sync extends AbstractQueuedSynchronizer {
abstract void lock();
// 省略相关代码
}
// 非公平锁对象
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) {
// 省略相关代码
}
}
// 公平锁对象
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
// 省略相关代码
}
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
public void lock() {
sync.lock();
}
public void unlock() {
sync.release(1);
}
总结
这篇文章的主要目的其实就是为了讲清楚一个问题,总结如下:
- ReentrantLock的锁内部实现通过NonfairSync和FairSync实现
- NonfairSync和FairSync继承Sync类,通过Sync对象保存NonfairSync和FairSync对象
- ReentrantLock的锁动作其实就是NonfairSync和FairSync的锁动作