ReentrantLock 可重入原理
从构造函数可以看到,ReentrantLock 默认为非公平锁实现,内部初始化了一个非公平同步器
public ReentrantLock() {
sync = new NonfairSync();
}
其内部的非公平同步器NonfairSync继承于抽象内部类Sync,Sync又继承自AbstractQueuedSynchronizer
ReentrantLock 可重入的原理依赖于NonfairSync继承的抽象内部类Sync中的两个方法,通过state计数的增加减少来实现可重入
nonfairTryAcquire()
这个方法在尝试获取锁时,如果锁已被占有,就用当前尝试获取锁的线程与当前占有锁的线程进行比较,如果是同一线程,就说明是发生了重入,此时给state计数加1,并返回true说明锁重入成功
tryRelease()
这个方法在尝试释放锁时,只有state计数成功减少到了0,才真正的释放锁并把占用锁的线程置为null
static final class NonfairSync extends Sync {
}
abstract static class Sync extends AbstractQueuedSynchronizer {
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 如果已经获得了锁, 线程还是当前线程, 表示发生了锁重入
else if (current == getExclusiveOwnerThread()) {
// state++
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
// state--
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
// 支持锁重入, 只有 state 减为 0, 才释放成功
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
}