AQS 是啥

AQS 在 Java 并发里,通常指 AbstractQueuedSynchronizer(抽象队列同步器)。

它是 JUC(java.util.concurrent)里很多锁和同步工具的底层框架。ReentrantLockSemaphoreCountDownLatchReentrantReadWriteLock 等都基于它实现。

一、一句话理解

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) 同一时刻只有一个线程能拿到 ReentrantLockReentrantReadWriteLock 写锁
共享模式(Shared) 多个线程可同时拿到 SemaphoreCountDownLatch、读写锁读锁

五、和 synchronized 的区别

synchronized 基于 AQS 的锁(如 ReentrantLock
实现 JVM 内置,监视器锁 Java 代码实现
灵活性 自动加锁解锁 tryLock、可中断、可超时、可公平
队列 依赖 JVM 实现 明确的 CLH 队列
条件变量 只有一个 wait/notify 可有多个 Condition

ReentrantLocksynchronized 功能多,就是因为 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 是什么?
  • ReentrantLocksynchronized 区别?
  • 公平锁 / 非公平锁怎么实现?

2. 理解并发工具的原理

知道 AQS 后,SemaphoreCountDownLatch 就不再是「黑盒 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 表示资源状态,用队列管理等待线程,子类只定义「怎么抢、怎么放」,其余排队、阻塞、唤醒都由它统一搞定。

相关推荐
m0_720245012 分钟前
1543.统计好三元组(简单)
开发语言·算法
EntyIU1 小时前
NFS离线部署
java
叠层归一研究院1 小时前
AGI 系统(八):符号范畴嵌入函子 — SymCat ↪ C_M107 严格化
c语言·开发语言·人工智能·算法·transformer·agi
明朝百晓生2 小时前
Deep RL learning[2026/8]
开发语言·javascript·人工智能
weixin-a153003083162 小时前
python-装饰器
开发语言·python
我的xiaodoujiao3 小时前
快速学习Python基础知识详细图文教程17--类型注解和断点调试
开发语言·python·学习·测试工具
OH_TPC3 小时前
HarmonyOS APP开发---“滤镜大师“图像处理App,需要用到这个库
java·图像处理·华为·harmonyos·鸿蒙
leoZ2315 小时前
AI 辅助开发的五道坎
开发语言·人工智能·视觉检测·bert·php·超分辨率重建·openvino
imaol15 小时前
链表 -- 环链表
java·前端·链表
程序员老陆5 小时前
Qt的QThread::usleep和FFmpeg的libavutil模块的av_usleep哪个精度高一些?
开发语言·qt·ffmpeg·音视频