锁与同步器的基础--AQS

什么是AQS

AQS全名AbstractQueueSynchronizer,可以翻译为抽象队列同步器
Abstract--说明该类需要被继承,提供实现的框架和一些必要的功能
事实上,AQS也的确提供了一个实现阻塞锁(blocking lock)和依赖于FIFO队列的同步器(Synchronizer)的框架
Queue--说明该类以队列的形式来存储数据
Synchronizer--说明该类的作用在于同步这一方面
我们来看一下UML图

AQS功能组成

用volatile变量state来标识状态
例如:

  1. ReentrantLock用state来记录重入次数
  2. semaphore用state表示当前可用信号的个数
  3. CountDownlatch用state表示计数器当前的值。

用Node存储线程及相关信息,而AQS本身的队列用于存储Node节点
用waitStatus记录当前线程等待状态
用setState()设置状态

用acquire()获取锁
用release()释放锁
最后两种方法的具体逻辑由子类实现

源码分析

Node

我们首先来看Node

static final class Node {
// 获取共享资源时等待
static final Node SHARED = new Node();
// 获取独占资源时等待
static final Node EXCLUSIVE = null;

// waitStatus的值,表示该结点(对应的线程)已被取消
static final int CANCELLED = 1;
// waitStatus的值,表示后继结点(对应的线程)需要被唤醒
static final int SIGNAL = -1;
// waitStatus的值,表示该结点(对应的线程)在等待某一条件
static final int CONDITION = -2;
/*waitStatus的值,表示有资源可用,新head结点需要继续唤醒后继结点(共享模式下,多线程并发释放资源,而head唤醒其后继结点后,需要把多出来的资源留给后面的结点;设置新的head结点时,会继续唤醒其后继结点)*/
static final int PROPAGATE = -3;

// 等待状态,取值范围,-3,-2,-1,0,1
volatile int waitStatus;
// 前驱结点
volatile Node prev; 
// 后继结点
volatile Node next; 
// 结点对应的线程
volatile Thread thread;
// 等待队列里下一个等待条件的结点 
Node nextWaiter; 
}
posted @ 2021-03-06 23:30  茕祇  阅读(71)  评论(0编辑  收藏  举报