final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { // state == 0,没有线程获取到锁 if (compareAndSetState(0, acquires)) { // CAS 修改成功,设置当前线程获得锁 setExclusiveOwnerThread(current); return true; } } // 有线程获取到锁,判断是不是当前线程获取到的 else if (current == getExclusiveOwnerThread()) { // 是当前线程获取到的,state + 1(acquires 传进来就是 1) int nextc = c + acquires; // 同一个线程可重入最大次数为 Integer.MAX_VALUE,超出后再加一即为负数 if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } // 获取锁失败,会进入 AQS 的等待队列中 return false;}
总结
非公平锁加锁流程
公平锁
主要特性:
加锁时不会尝试修改,直接走 acquire() 流程
在 tryAcquire() 中修改状态前先判断自己是否处于队列头部
java
/** * Sync object for fair locks */static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; final void lock() { // 直接走 AQS 的 acquire() 流程,会调用 tryAcquire() 方法 acquire(1); } /** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { // state == 0,没有线程获取到锁 if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { // 阻塞等待队列中没有线程,并且 CAS 修改状态成功,设置当前线程获得锁 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; }}
总结
公平锁加锁流程
释放锁
公平锁和非公平锁的释放锁相同,是 Sync 中的 tryRelease() 方法。
java
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); return free;}