AQS 是实现 ReentrantLock、CountDownLatch、Semaphore、FutureTask 等类的基础。
AQS属性
//头结点 当前持有锁的线程
private transient volatile Node head;
// 阻塞的尾节点,每个新的节点进来,都插入到最后,也就形成了一个链表
private transient volatile Node tail;
// 这个是最重要的,代表当前锁的状态,0代表没有被占用,大于 0 代表有线程持有当前锁
// 这个值可以大于 1,是因为锁可以重入,每次重入都加上 1
private volatile int state;
//代表当前持有独占锁的线程
private transient Thread exclusiveOwnerThread;
AQS里面有两种队列:阻塞队列和等待队列,其中每个线程被包装成一个 Node 实例,数据结构(thread + waitStatus + pre + next)是链表
static final class Node {
// 当前节点处于共享模式的标记
static final Node SHARED = new Node();
// 当前节点处于独占模式的标记
static final Node EXCLUSIVE = null;
// ======== 下面的几个int常量是给waitStatus用的 ===========
// 代码此线程取消了争抢这个锁
static final int CANCELLED = 1;
// 释放资源后需唤醒后继节点
static final int SIGNAL = -1;
//等待condition唤醒
// CONDITION队列中的状态,CLH队列中节点没有该状态,当将一个node从CONDITION队列中transfer 到CLH队列中时,状态由CONDITION转换成0
static final int CONDITION = -2;
//工作于共享锁状态,需要向后传播,
//比如根据资源是否剩余,唤醒后继节点该状态表示下一次节点如果是Shared的,则无条件获取锁。
static final int PROPAGATE = -3;
// =====================================================
// 取值为上面的1、-1、-2、-3,或者0(初始)
volatile int waitStatus;
// 前驱节点
volatile Node prev;
// 后继节点
volatile Node next;
volatile Thread thread;
}