参考资料:
https://tech.meituan.com/2019/12/05/aqs-theory-and-apply.html
https://www.cnblogs.com/waterystone/p/4920797.html
AQS是一种提供原子式管理同步状态、阻塞和唤醒线程功能以及队列模型的简单框架。
标题AQS核心思想:
- 如果被请求的共享资源空闲,那么就将当前请求资源的线程设置为有效的工作线程,将共享资源设置为锁定状态;
- 如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配。这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中。
AQS使用一个Volatile的int类型的成员变量来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作,通过CAS完成对State值的修改。
AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。
数据结构:
/**
* The synchronization state.
*/
private volatile int state;
/**
* Head of the wait queue, lazily initialized. Except for
* initialization, it is modified only via method setHead. Note:
* If head exists, its waitStatus is guaranteed not to be
* CANCELLED.
* 双向队列的头节点
*/
private transient volatile Node head;
/**
* Tail of the wait queue, lazily initialized. Modified only via
* method enq to add new wait node.
*/
private transient volatile Node tail;
static final class Node {
/** Marker to indicate a node is waiting in shared mode */
static final Node SHARED = new Node();
/** Marker to indicate a node is waiting in exclusive mode */
static final Node EXCLUSIVE = null;
/** waitStatus value to indicate thread has cancelled */
static final int CANCELLED = 1;
/** waitStatus value to indicate successor's thread needs unparking */
static final int SIGNAL = -1;
/** waitStatus value to indicate thread is waiting on condition */
static final int CONDITION = -2;
/**
* waitStatus value to indicate the next acquireShared should
* unconditionally propagate
*/
static final int PROPAGATE = -3;
/**
* Status field, taking on only the values:
* SIGNAL: 该节点阻塞了后续的节点。当前节点release或者cancel时,要唤醒后继节点。
* CANCELLED: 该节点由于timeout或者被中断而取消了。该节点将一直保持现状,不会改变。
* CONDITION: 该节点在等待队列中,等待唤醒。当其他线程调用了Condition的signal()方法 后,CONDITION状态的结点将从等待队列转移到同步队列中,等待获取同步锁。
* PROPAGATE: 共享模式下,前继结点不仅会唤醒其后继结点,同时也可能会唤醒后继的后继结点。
* 新结点入队时的默认状态为0。
*/
volatile int waitStatus;
volatile Node prev;
volatile Node next;
/**
* The thread that enqueued this node. Initialized on
* construction and nulled out after use.
*/
volatile Thread thread;
/**
* 如果是独占模式,则nextWaiter指向的是下一个等待该条件的Node
* 如果是共享模式,则nextWaiter会被设置成一个特殊值:SHARED
*/
Node nextWaiter;
}
一个节点的主要流程: