1 概述
AQS是AbstratQueuedSynchronizer的缩写,即抽象同步列,JUC中锁的底层就是基于该抽象类实现的。其类图如下:
该类是一个FIFO的双向队列,队列中的元素时Node(是AQS的静态内部类)。
Node中的thread变量用来存放进入AQS的线程,Node中的SHARE用来标记该线程是获取共享资源时被挂入AQS的;EXCLUSIVE是用来标记该线程是获取独占资源时被挂入AQS的;waitStatus可以用来表示该线程的状态:线程被取消了CANCELLED,线程被挂在条件队列上CONDITION,线程需要被唤醒SIGNAL,释放共享资源时需要通知其他节点PROPAGATE;prev用来记录当前节点的前驱结点;next用来记录当前节点的后驱节点。
ConditionObject是AQS的内部类,是一个条件变量,用来结合锁实现线程同步,后面将详细介绍。
AQS中还有一个状态变量state,该变量可以用来表示锁的一些状态,比如对于独占锁ReentrantLock,state可以用来表示其可重入次数,对于ReentrantReadWriteLock来说,state的高十六位表示读状态,也就是读锁的获取次数,低十六位用来表示写锁的可重入次数。
2 主要方法
线程同步的关键就是对state状态变量进行操作,而操作state又可以分为独占方式和共享方式,独占方式下获取和释放资源的方式是:void acquire(int arg), void acquireInterruptibly(int arg), boolean release(int arg);共享方式下获取和释放资源的方式是void acquireShared(int arg), void acquireSharedInterruptibly(int arg), boolean releaseShared(int arg)。下面主要对独占方式下的acquire(int arg)方法和release(int arg)方法进行介绍。
2.1 acquire(int arg)
首先来看以下该方法的源码,首先尝试获取独占资源,获取失败则将自己挂到阻塞队列尾部
public final void acquire(int arg) {
//tryAcquire()是尝试获取资源的方法,由AQS具体的子类来实现
if (!tryAcquire(arg) &&//tryAc