基于AQS的ReentrantLock如何为?
摘要:基于AQS实现的ReentrantLock 这里的源码用的Java8版本 lock方法 当ReentrantLock类的实例对象尝试获取锁的时候,调用lock方法, 会进入sync的lock方法,其中Sync是ReentrantLock的一
基于AQS实现的ReentrantLock
这里的源码用的Java8版本
lock方法
当ReentrantLock类的实例对象尝试获取锁的时候,调用lock方法,
会进入sync的lock方法,其中Sync是ReentrantLock的一个内部类,ReentrantLock构造方法会默认使用非公平锁NonfairSync,这个类是继承于Sync的
final void lock() {
if (!initialTryLock())
acquire(1);
}
// 其中Sync的initialTryLock是抽象方法,需要看非公平锁实现方法
[!TIP]
在这里是第一次尝试获取锁
由于ReentrantLock是个可重入锁,判断里有重入的判断
final boolean initialTryLock() {
Thread current = Thread.currentThread();
// 获取当前线程的对象
if (compareAndSetState(0, 1)) { // first attempt is unguarded
// 用CAS比较state状态是否为0(无人持有锁),如果是,就转为1(获取到锁)
setExclusiveOwnerThread(current);
// 将当前进程设置为拥有锁的线程
return true;
} else if (getExclusiveOwnerThread() == current) {
// 当前线程为拥有锁的线程(重复获取),重入
int c = getState() + 1;
if (c < 0) // overflow
// 负数,state是个int类型数据,超出可能导致溢出变为负数
throw new Error("Maximum lock count exceeded");
setState(c);
// 设置新的state
return true;
} else
// 已有线程占锁,返回为false
return false;
}
然后开始调用acquire方法,传入1
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
调用tryAcquire()方法,其中tryAcquire()方法是一个只有抛出异常的方法,需要重写,我们看非公平锁的写法
[!TIP]
这是第二次获取锁
protected final boolean tryAcquire(int acquires) {
if (getState() == 0 && !hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
这里,如果state是0,即没有线程占用锁的情况下getState() == 0这个为真!hasQueuedPredecessors()执行这个方法,这个方法会检查是否已经出现了等待队列
public final boolean hasQueuedPredecessors() {
Thread first = null; Node h, s;
if ((h = head) != null && ((s = h.next) ==
