ReentrantLock源码阅读与理解
tips:在读这篇文章之前请先理解本博客对AQS这个类的阐述:传送门。本文针对的是理解AQS框架的基础上进行说明的。
简介:重入锁具有可重入,可限时,可中断,可公平四个特性。
几个属性和几个方法:
//Sync这个类至关重要继承了AQS,也是重入锁的核心类之一
private final Sync sync;
//这个抽象类在重入锁中有两个实现类NonfairSync和FairSync,分别为非公平实现类和公平实现类因为获取锁的方法不同而分成了两个实现类。
abstract static class Sync extends AbstractQueuedSynchronizer {
//关键的方法,尝试释放锁,会根据返回值判断是否释放成功,如果释放成功则去唤醒下一个线程否则继续释放。
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
//设置执行的线程为null
setExclusiveOwnerThread(null);
}
//更改state状态
setState(c);
return free;
}
}
//看看非公平锁的锁获取方式,会根据函数的返回值是true或者false来判断是否获取成功,以便AQS来决定是否将其加入等待队列中去。
static final class NonfairSync extends Sync {
//非公平所实现的关键是Lock函数
final void lock() {
//当线程执行lock的时候就会先去尝试获取锁,这也是跟公平锁最大区别的地方
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
//nonfairTryAcquire函数,入参基本都是1
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//CAS尝试去改变state状态,如果成功则获取锁
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;
}
static final class FairSync extends Sync {
private static final long
final void lock() {
//公平所和非公平锁最大的区别,在于lock方法
acquire(1);
}
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;
}
}
}