AbstractQueuedSynchronizer简称AQS,ReentrantLock,ReentrantReadWriteLock,CountDownLatch,Semaphore等等这些锁都是基于AQS实现的。AQS核心主要实现了锁的状态的同步,队列排队、唤醒管理,锁的释放等底层功能。主要基于state属性来控制锁的可用状态,通过维护一个CLH双向链表队列来管理并发获取锁的线程进行排队。
主要属性
/**
* 队列头节点,延迟初始化,除了初始化时仅能通过setHead方法修改
*/
private transient volatile Node head;
/**
* 队列尾节点,延迟初始化,仅通过enq方法修改添加等待节点
*/
private transient volatile Node tail;
/**
* 同步器状态
*/
private volatile int state;
CLH队列节点属性
static final class Node {
/** 共享锁标记 */
static final Node SHARED = new Node();
/** 独占锁标记 */
static final Node EXCLUSIVE = null;
/** 节点取消排队,可能由于超时或者中断 */
static final int CANCELLED = 1;
/** 当前节点的下个节点是阻塞或即将阻塞,当节点释放锁或取消时应该唤醒unpark下个节点 */
static final int SIGNAL = -1;
/** 条件队列节点 */
static final int CONDITION = -2;
/**
* 标识下个节点无条件传播(适用与共享锁)
*/
static final int PROPAGATE = -3;
//节点等待状态,0,CANCELLED,SIGNAL,CONDITION,PROPAGATE
volatile int waitStatus;
//上个节点
volatile Node prev;
//下个节点
volatile Node next;
//节点线程
volatile Thread thread;
/**
* 共享锁时值为 SHARED
* 条件队列时指向条件队列下个节点
*/
Node nextWaiter;
加锁流程
核心方法
//判断当前请求是否需要排队
public final boolean hasQueuedPredecessors() {
Node t = tail;//尾节点
Node h = head;//头节点
Node s;
return h != t &&//h==t时代表没有线程排队,见:java.util.concurrent.locks.AbstractQueuedSynchronizer#enq()
((s = h.next) == null || s.thread != Thread.currentThread());
//
//s.thread != Thread.currentThread() 判断第一个排队线程是否是当前线程
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。