AQS系列之AbstractQueuedSynchronizer基础分析
一、简介
AQS是JDK并发包中的一个抽象类,全称为AbstractQueuedSynchronizer,即抽象队列同步器,是一系列同步实现的模板类,如锁Lock,信号量Semaphore,倒排计数器CoundDownLatch等都是基于AQS实现的,同时还提供了Condition对象,其await和sign、signAll对象可以用于代替Object的wait和notofy、notifyAll方法。
CLH队列是是一种先进先出FIFO的双向队列,AQS对其实现微调,但原理不变,用于实现同步阻塞。
AQS中实际上包括两个队列,同步队列用于排斥锁和共享锁,条件队列用于Condition对象的等待和唤醒。
二、内部类Node
Node是AQS的内部类,用于定义CLH队列中的节点。
volatile int waitStatus;
volatile Node prev;
volatile Node next;
volatile Thread thread;
Node nextWaiter;
Node主要有以上5个成员变量,大概含义如下
- 同步队列的前驱节点和后继节点 prev && next
- 节点中的线程 thread
- 节点状态 waitStatus
节点分为两类共四个状态,用整型表示,大于0表示无效,小于0表示有效,具体如下:
CANCELlED: 1 等待超时或者线程被中断而取消
SIGNAL: -1 后续节点被阻塞,也有可能是即将被阻塞(节点阻塞前将前驱节点状态置为SIGNAL)
CONDITION: -2 用于条件队列
PROPAGATE:-3 用于共享锁,在释放共享锁发挥作用 - 条件队列的下一个节点 nextWaiter
主要用于条件队列。由于条件队列是建立在排斥锁的前提下的,也可以用来检查和表示锁的模式,当且仅当该字段为空节点(New Node())时代表共享模式。
三、AbstractQueuedSynchronizer
1. 成员变量
//头节点,指向队列中第一个节点。实际使用过程中要么是初始化的节点,要么代表最后一个获取资源成功的节点
private transient volatile Node head;
//尾节点,指向队列中最后一个节点
private transient volatile Node tail;
//状态,实际使用中可以表示资源数或者获取资源成功的线程、锁重入次数等等
private volatile int state;
2. 对外方法简介
下面是几个对外的公共方法,可以分为排斥锁和共享锁,也可以分为获取资源和释放资源,也可以分为是否响应中断,是否支持超时