上一篇文章重点分析了AQS的源码,有了这个认识,我们再看ReentrantLock的源码,会简单很多,来看下这个类
// 创建一个锁
ReentrantLock lock = new ReentrantLock();
// 默认是非公平锁,提升效率
public ReentrantLock() {
sync = new NonfairSync();
}
// 属性
private final Sync sync;
看下Sync这个ReentrantLock的静态内部抽象类
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
abstract void lock();
// 非公平式尝试独占获取资源实现
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
// 0表示没有任何线程占用
if (c == 0) {
// 设置成功,非公平,不管前面是否有其他线程抢占资源
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;
}
// 独占式释放锁自定义实现
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;
setExclusiveOwnerThread(null);
}
setState(c);
// 如果是重入了多次的话,返回也是false
return free;
}
// 判断是否是当前线程持有资源
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
...
}
NonfairSync继承了Sync抽象类,来看代码
static final class NonfairSync extends Sync {
// 非公平抢占资源,可以看到先尝试抢占一次资源(可耻的插队行为)
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
// 插队失败再调用独占式获取资源方法acquire
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
// 调用nonfairTryAcquire方法,上面有分析过
return nonfairTryAcquire(acquires);
}
}
FairSync继承了Sync抽象类来看代码,来看代码
static final class FairSync extends Sync {
//公平锁,老实排队获取
final void 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;
}
}
查看释放锁方法
public void unlock() {
// 一次释放一个资源
sync.release(1);
}