AQS,全称 AbstractQueuedSynchronizer,是 Java 并发包中用于构建锁和其他同步器的基础框架。理解 AQS 的关键在于掌握它的内部状态管理、等待队列机制以及它如何利用 CAS(Compare-And-Swap)实现线程同步。下面从几个方面详细说明如何理解 AQS:
1. AQS 的基本概念
-
内部状态(state):
AQS 通过一个volatile int state
来表示同步状态。不同的同步器(比如 ReentrantLock、Semaphore、CountDownLatch 等)会对 state 的含义有不同的定义。例如,在 ReentrantLock 中,state 表示锁的重入次数;在 Semaphore 中,state 表示可用的许可证数量。 -
等待队列(CLH 队列):
当线程获取锁失败时,它们会被封装成节点(Node)加入到一个 FIFO 队列中,这个队列通常称为 CLH(Craig, Landin, and Hagersten)等待队列。等待队列保证了线程的公平性和等待顺序。
2. AQS 的工作原理
2.1 CAS 操作与内部状态修改
- CAS 原子操作:
AQS 依赖 CAS 来更新内部状态,确保在多线程并发环境下对 state 的修改是原子的。比如,当线程尝试获取锁时,会通过 CAS 检查并修改 state,如果成功则说明锁已获取;如果失败,则进入等待队列。
2.2 同步状态的获取与释放
-
获取同步状态:
AQS 定义了抽象方法tryAcquire(int arg)
(或tryAcquireShared(int arg)
用于共享模式),子类需要实现这些