Java - AQS原理
2020-05-05 本文已影响0人
万福来
AQS 实现原理
AQS:AbstractQueuedSynchronizer,即队列同步器。它是构建锁或者其他同步组件的基础框架(如ReentrantLock、ReentrantReadWriteLock、Semaphore等),它是JUC并发包中的核心基础组件。
AQS的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态。作者推荐采用静态内部实现类继承AQS抽象类,并通过组合模式来实现锁的功能。AQS其实就是模板模式的实现。
AQS主要提供了两类方法来实现同步器功能
//独享式的尝试获取
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
//独享式的尝试释放
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
}
// 共享式的尝试获取
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
// 共享式的尝试释放
protected boolean tryReleaseShared(int arg) {
throw new UnsupportedOperationException();
}
// 判断是否为独占式
protected boolean isHeldExclusively() {
throw new UnsupportedOperationException();
}
- 独享式的模板方法主要用于构建互斥锁,例如ReentrantLock
- 共享式的模板方法主要用于构建共享式的锁,例如Semaphore,CountDownLatch,ReadWriteLock;
AQS使用一个int类型的成员变量state来表示同步状态,当state>0时表示已经获取了锁,当state = 0时表示释放了锁。它提供了三个方法(getState()、setState(int newState)、compareAndSetState(int expect,int update))来对同步状态state进行操作,当然AQS可以确保对state的操作是安全的。
AQS通过内置的FIFO同步队列来完成资源获取线程的排队工作,如果当前线程获取同步状态失败(锁)时,AQS则会将当前线程以及等待状态等信息构造成一个节点(Node)并将其加入同步队列,同时会阻塞当前线程,当同步状态释放时,则会把节点中的线程唤醒,使其再次尝试获取同步状态。