什么是AQS
aqs即AbstractQueuedSynchronizer(队列同步器)抽象类的简称,它是Java并发用来构建锁,和其他同步组件的基础框架,内部使用先进先出的同步队列实现,比如 ReentrantLock、CountDownLatch 和 Semaphore 等都是基于 AQS 实现的
AQS的独占锁和共享式锁
独占锁模式下,每次只能有一个线程能持有锁,ReentrantLock就是以独占方式实现的互斥锁。共享锁,则允许多个线程同时获取锁,并发访问 共享资源,如:ReadWriteLock。AQS的内部类Node定义了两个常量SHARED和EXCLUSIVE,他们分别标识 AQS队列中等待线程的锁获取模式
AQS数据结构:
节点之间相互引用,头节点指向尾节点,每个节点存储内容还包括当前节点的状态
竞争失败的线程会打包成Node(源码里是aqs类的一个内部类)放到同步队列,
了解其中的方法
模板方法:(重写)
独占式获取
accquire
acquireInterruptibly
tryAcquireNanos
共享式获取
acquireShared
acquireSharedInterruptibly
tryAcquireSharedNanos
独占式释放锁
release
共享式释放锁
releaseShared
需要子类覆盖的流程方法
独占式获取 tryAcquire
独占式释放 tryRelease
共享式获取 tryAcquireShared
共享式释放 tryReleaseShared
这个同步器是否处于独占模式 isHeldExclusively
同步状态state:
getState:获取当前的同步状态
setState:设置当前同步状态
compareAndSetState 使用cas方式来设置状态
使用CAS设置状态,保证状态设置的原子性
竞争失败的线程会打包成Node放到同步队列,Node可能的状态值waitStatus:
CANCELLED:线程等待超时或者被中断了,需要从队列中移走,为1
SIGNAL:后续的节点等待状态,当前节点,通知后面的节点去运行,为-1
CONDITION :当前节点处于等待队列,为-2
PROPAGATE:共享,表示状态要往后面的节点传播,值为-3
0,表示初始状态
独占式同步状态获取与释放
Node静态内部类部分源码
volatile Node prev;//指向前面节点的node
/**
* Link to the successor node that the current node/thread
* unparks upon release. Assigned during enqueuing, adjusted
* when bypassing cancelled predecessors, and nulled out (for
* sake of GC) when dequeued. The enq operation does not
* assign next field of a predecessor until after attachment,
* so seeing a null next field does not necessarily mean that
* node is at end of queue. However, if a next field appears
* to be null, we can scan prev's from the tail to
* double-check. The next field of cancelled nodes is set to
* point to the node itself instead of null, to make life
* easier for isOnSyncQueue.
*/
volatile Node next;//指向后面节点的node
/**
* The thread that enqueued this node. Initialized on
* construction and nulled out after use.
*/
volatile Thread thread;//争夺锁失败的线程