基于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) ==
阅读全文