ReentrantLock源码解读
在看此文章前,先要了解一下上一篇文章AbstractQueuedSynchronizer
(AQS)。
ReentrantLock
ReentrantLock锁的实现分为两种(公平锁、非公平锁),默认是非公平锁。
ReentrantLock lock = new ReentrantLock();
Sync(公平锁和非公平锁都继承此抽象类)
nonfairTryAcquire(尝试获取锁)
/**
* @param acquires state的增加值
*/
final boolean nonfairTryAcquire(int acquires) {
// 获取当前线程
final Thread current = Thread.currentThread();
// 获取state,0为未被线程持有,大于0为已被线程持有
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
// 设置持有的线程为当前线程
setExclusiveOwnerThread(current);
return true;
}
}
// 【可重入】如果当前线程已经持有
else if (current == getExclusiveOwnerThread()) {
// 当前的state + acquires,在NonfairSync中,即当前state+1
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
// 为什么这里用setState,而不是compareAndSetState,因为当前线程已经持有,setState不会造成其他冲突
setState(nextc);
return true;
}
return false;
}
tryRelease(尝试释放锁)
/**
* @param releases state的增加值
*/
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
// 判断当前线程是否为持有锁的线程,【解铃还须系铃人】
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// 释放标识
boolean free = false;
// 当state为0的时候,才表明已经没有线程持有
if (c == 0) {
// 标识可以释放
free = true;
setExclusiveOwnerThread(null);
}
// 设置state
setState(c);
return free;
}
NonfairSync(非公平锁)
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
// 如果状态为0(没有线程占用),则设置为1,此方法在AbstractQueuedSynchronizer中
if (compareAndSetState(0, 1))
// 设置当前持有的线程,此方法在AbstractOwnableSynchronizer中
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
// 试图获取锁
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
FairSync(公平锁)
unlock
public void unlock() {
sync.release(1);
}