抽象队列同步器AQS
AQS全名为AbstractQueuedSynchronizer,为java并发包中提供的类。提供了对资源占用,释放,线程的等待、唤醒等接口和具体实现,
可以用在各种需要控制资源争用的场景中。(ReentrantLock/CountDownLatch/Semphore)
AQS中定义了八个比较重要的方法:
acquire、acruireShared:定义了资源争用的逻辑,如果没拿到,则等待
tryAcquire、tryAcquireShared:实际执行占用资源的逻辑,如何判定由使用者具体去实现
release、releaseShared:定义资源释放的逻辑,释放之后,通知后续节点进行争抢
tryRelease、tryReleaseShared:定义执行资源释放的操作,具体的AQS使用者去实现
资源占用流程
以ReentrantLock为例,分析AQS的使用。由于ReentrantLock是独占锁,所以会涉及到 acquire、tryAcquire、release、tryRelease四个方法。
ReentrantLock中Sync类继承了AQS,其中关键代码如下:
abstract static class Sync extends AbstractQueuedSynchronizer { /** * Performs {@link Lock#lock}. The main reason for subclassing * is to allow fast path for nonfair version. */ abstract void lock(); .... /** *非公平获取锁,每次获取时都尝试获取一次,不管前面是否有其他 *线程也在尝试获取,获取失败则加入等待队列 * 获取成功则将锁持有者设为当前线程 */ final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); 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; } /** *尝试释放锁 *即将state变量减一,当state为0时返回释放成功 */ 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; } ... }
ReentrantLock中有公平锁和非公平锁两种实现。在ReentrantLock中对应了两个类,NonfairSync和FairSync,它们都继承了Sync。
FairSync关键代码如下:
static final class FairSync extends Sync { ··· /** *加锁方法,首先调用tryAcquire方法,成功则获取锁 *否则通过aqs提供的方法将当前线程加入等待队列 */ final void lock() { acquire(1); } /** *如果state为0则尝试获取锁,如果前面有线程也尝试获取锁则把当前线程加入等待队列 *state不为0则则判断持有锁的线程是否时当前线程,是则state加一(锁的可重入机制) */ 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; } }
NonfairSync关键代码如下:
static final class NonfairSync extends Sync { ··· /** *非公平锁加锁时总是先尝试获取锁 *即尝试通过CAS将state由0设为1 * 设置失败则调用acquire方法 */ final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } /** * tryAcquire方法调用父类Sync的nonfairTryAcquire方法 */ protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }
接下来再查看ReentrantLock的加锁与解锁方法,即在调用Sync的acruire和release方法:
... public void lock() { sync.lock(); } ... public void unlock() { sync.release(1); } ...