AbstractQueuedSynchronizer(AQS)

AbstractQueuedSynchronizer,简称AQS。AQS是一个用来构建锁和同步器的框架。

数据结构

核心成员变量

1
private volatile int state;//共享变量,使用volatile修饰保证线程可见性

核心代码:

1
2
3
4
5
6
7
public final void acquire(int arg) {
//先看同步状态是否获取成功,如果成功则方法结束返回
//若失败则先调用addWaiter()方法再调用acquireQueued()方法
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}

alt

alt
双端双向链表

AQS维护一个共享资源state,通过内置的FIFO来完成获取资源线程的排队工作。(这个内置的同步队列称为”CLH”队列)。该队列由一个一个的Node结点组成,每个Node结点维护一个prev引用和next引用,分别指向自己的前驱和后继结点。AQS维护两个指针,分别指向队列头部head和尾部tail。

当线程获取资源失败(比如tryAcquire时试图设置state状态失败),会被构造成一个结点加入CLH队列中,同时当前线程会被阻塞在队列中(通过LockSupport.park实现,其实是等待态)。当持有同步状态的线程释放同步状态时,会唤醒后继结点,然后此结点线程继续加入到对同步状态的争夺中

  1. 独占式
    tryAcquire tryRelease
  2. 共享式
    tryAcquireShared tryReleaseShared

ReentrantLock(独占式,默认非公平锁效率更高,减少线程上下文切换;使用Condition可以更进一步细粒度控制挂起和唤醒),Semaphore,其他的诸如ReentrantReadWriteLock(写 独占式;读 共享式),SynchronousQueue,FutureTask等等皆是基于AQS。

LockSupport;Unsafe 实现