ReentrantLock支持公平锁和非公平锁,默认构造使用非公平锁实现。
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
首先查看获取锁 lock
方法
// ReentrantLock.NonfairSync
final void lock() {
// CAS设置同步状态state为1,成功表明获取锁成功,设置当前线程为独占锁的持有线程
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1); // CAS失败,重新尝试获取锁
}
// AbstractQueuedSynchronizer
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
// ReentrantLock.NonfairSync
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires); // 尝试获取非公共独占锁
}
// ReentrantLock.Sync
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState(); // 获取同步状态state值
if (c == 0) { // 0代表没有被线程持有,CAS获取锁,获取成功则将当前线程设置为独占锁的持有线程
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 当前线程与独占锁持有者线程相同
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc); // 设置锁重入次数
return true;
}
return false;
}
对于公平锁实现,仅仅在 tryAcquire
中添加判断是否有等待获取锁的线程等待时间比当前线程久。
// ReentrantLock.FairSync
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
// 相比非公平锁,添加判断是否有线程等待获取锁的时间比当前线程还久
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
释放锁 unlock
方法
// ReentrantLock
public void unlock() {
sync.release(1);
}
// AbstractQueuedSynchronizer
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
// ReentrantLock.Sync
protected final boolean tryRelease(int releases) {
int c = getState() - releases; // 递减锁重入次数
// 判断当前线程是否为独占锁持有线程,否则抛出异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false; // 锁释放标识
// c等于0,说明锁已经释放,设置锁释放标识为true
if (c == 0) {
free = true;
setExclusiveOwnerThread(null); // 置空独占锁持有线程
}
setState(c); // 设置同步状态state
return free; // 返回锁释放标识
}