AQS 在 Java 并发里,通常指 AbstractQueuedSynchronizer(抽象队列同步器)。
它是 JUC(java.util.concurrent)里很多锁和同步工具的底层框架。ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock 等都基于它实现。
一、一句话理解
AQS = 用「一个状态变量 + 一个等待队列」管理线程抢资源、排队、唤醒的通用模板。
你可以把它想成:银行叫号系统
state → 当前还有几个窗口/名额(比如锁是否被占用)
CLH 队列 → 没抢到的人排队
park/unpark → 叫到号唤醒你
二、核心组成
1. state(状态)
一个 volatile int,表示同步状态,含义由子类定义:
| 工具 | state 含义 |
|---|---|
ReentrantLock |
0=未锁,>0=被锁(可重入次数) |
Semaphore |
剩余许可数 |
CountDownLatch |
还剩几个线程没完成 |
ReentrantReadWriteLock |
高 16 位=读锁数,低 16 位=写锁数 |
2. CLH 双向队列
抢不到的线程会封装成 Node 放进 FIFO 队列里等待,避免大量线程空转(忙等)。
3. 模板方法
子类只需实现两个方法:
// 尝试获取资源(抢锁/抢许可)
protected boolean tryAcquire(int arg)
// 尝试释放资源(放锁/还许可)
protected boolean tryRelease(int arg)
AQS 负责通用的排队、阻塞、唤醒逻辑。
三、工作流程(以独占锁为例)

获取锁(简化理解)
public final void acquire(int arg) {
// 1. 先试着抢
if (!tryAcquire(arg)) {
// 2. 抢不到就入队
// 3. 自旋检查前驱是否是队头
// 4. 还不行就 park 挂起
}
}
释放锁
public final boolean release(int arg) {
if (tryRelease(arg)) {
// 唤醒队列里下一个等待线程
unparkSuccessor(head);
return true;
}
return false;
}
四、两种模式
| 模式 | 说明 | 典型实现 |
|---|---|---|
| 独占模式(Exclusive) | 同一时刻只有一个线程能拿到 | ReentrantLock、ReentrantReadWriteLock 写锁 |
| 共享模式(Shared) | 多个线程可同时拿到 | Semaphore、CountDownLatch、读写锁读锁 |
五、和 synchronized 的区别
synchronized |
基于 AQS 的锁(如 ReentrantLock) |
|
|---|---|---|
| 实现 | JVM 内置,监视器锁 | Java 代码实现 |
| 灵活性 | 自动加锁解锁 | 可 tryLock、可中断、可超时、可公平 |
| 队列 | 依赖 JVM 实现 | 明确的 CLH 队列 |
| 条件变量 | 只有一个 wait/notify |
可有多个 Condition |
ReentrantLock 比 synchronized 功能多,就是因为 AQS 提供了可扩展的模板。
六、代码里长什么样
ReentrantLock 内部有个继承 AQS 的同步器:
// 简化示意,帮助理解
class Sync extends AbstractQueuedSynchronizer {
protected boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
// 没人占锁,CAS 抢
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
} else if (current == getExclusiveOwnerThread()) {
// 重入:同一线程再加锁
setState(c + acquires);
return true;
}
return false;
}
protected boolean tryRelease(int releases) {
// 释放锁,state 减到 0 时真正放开
...
}
}
业务代码只管 lock() / unlock(),排队和唤醒由 AQS 统一处理。
七、为什么重要
1. 面试常考
- AQS 是什么?
ReentrantLock和synchronized区别?- 公平锁 / 非公平锁怎么实现?
2. 理解并发工具的原理
知道 AQS 后,Semaphore、CountDownLatch 就不再是「黑盒 API」。
3. 和项目的关系
| 场景 | 可能用到 |
|---|---|
| 接口限流 | Semaphore |
| 等待多个任务完成 | CountDownLatch |
| 需要可中断/超时加锁 | ReentrantLock |
| 线程池 | 底层也依赖 AQS 协调 |
你们前面聊的数据库锁、分布式锁、事务,解决的是数据层并发;AQS 解决的是单机 JVM 内线程同步,层次不同,但都服务于「多线程不打架」。
八、常见考点速记
AQS 三件套:
state → 同步状态
CLH 队列 → 等待线程排队
CAS + park → 抢资源 / 阻塞 / 唤醒
子类实现:
tryAcquire → 怎么抢
tryRelease → 怎么放
基于 AQS 的工具:
ReentrantLock
ReentrantReadWriteLock
Semaphore
CountDownLatch
CyclicBarrier(内部也用 ReentrantLock + Condition)
九、一句话总结
AQS 是 Java 并发包的「发动机」:用 state 表示资源状态,用队列管理等待线程,子类只定义「怎么抢、怎么放」,其余排队、阻塞、唤醒都由它统一搞定。