深入理解 AbstractQueuedSynchronizer (AQS):Java 并发的排队管家

最近在准备面试,正把平时积累的笔记、项目中遇到的问题与解决方案、对核心原理的理解,以及高频业务场景的应对策略系统梳理一遍,既能加深记忆,也能让知识体系更扎实,供大家参考,欢迎讨论。

AbstractQueuedSynchronizer 就是:

👉 "一个抽象的、基于队列的同步器"

  • 抽象:自己不能直接用,得继承。
  • 排队:管理等待线程的队列。
  • 同步器:用于实现各种同步工具(可重入锁、信号量、闭锁...)。

在 Java 并发编程里,虽然平时我们写代码常用的是 ReentrantLock(独占锁)CountDownLatch(共享锁)Semaphore,但它们的底层都是靠 AQS 实现的。


1. AQS 是什么?

一句话:

👉 AQS 就是一个排队管家

  • state :state 是个抽象的同步状态,不同场景下有不同解释。
    • ReentrantLock 里,state 表示 锁的重入次数0 代表未加锁,>0 表示已加锁,并统计重入层数)。
    • CountDownLatch 里,state 表示 计数值(倒计时还有几个)。
    • Semaphore 里,state 表示 剩余的许可数量
  • 队列 :没抢到资源的线程,会被放进一个 FIFO 队列
  • 阻塞与唤醒 :没轮到的线程,先 park(睡觉);轮到时,再 unpark(叫醒)。

AQS 不管具体规则,只提供排队机制。子类自己定义"怎么抢""怎么放",AQS 负责排队+调度"。


2. 核心流程

拿独占锁为例:

  1. 线程调用 lock(),底层走到 AQS 的 acquire()

  2. tryAcquire():尝试直接抢锁(子类自己实现)。

  3. 如果抢不到:

    • 把当前线程打包成 Node → 入队。
    • 调用 LockSupport.park() 把线程挂起。
  4. 当持有锁的线程 unlock()

    • AQS 调用 tryRelease() 释放资源。
    • 唤醒队列里下一个节点的线程。
  5. 被唤醒的线程重新去尝试抢锁。


3. ReentrantLock 如何用 AQS?

ReentrantLock 就是基于 AQS 实现的独占锁(独占模式),它的实现类 Sync 继承了 AQS,并重写了关键方法:

  • tryAcquire(int arg):如果没人占用锁,或者自己重入 → 修改 state + 1 并返回 true。
  • tryRelease(int arg): state - 1,若为 0 表示锁完全释放。

剩下的排队、阻塞、唤醒,全由 AQS 管理。


4. CountDownLatch 如何用 AQS?

CountDownLatch 基于 AQS 的 共享模式(Shared) 实现,它的内部类 Sync 继承了 AQS,并重写了关键方法:

  • tryAcquireShared(int arg):检查 state(计数器)是否为 0,如果为 0 → 返回正值,表示可以获取;否则返回负值,表示线程需要排队等待。
  • tryReleaseShared(int arg):原子将 state 减 1,如果减到 0 → 返回 true,AQS 会唤醒所有等待线程。

剩下的排队、阻塞、唤醒,全由 AQS 管理。

很好的抽象,该交给子类去扩展的就封装抽象方法,让子类决定是否支持共享模式


相关推荐
Chengbei111 分钟前
CVE-2025-24813 Tomcat 最新 RCE 分析复现
java·安全·web安全·网络安全·tomcat·系统安全·网络攻击模型
AAA简单玩转程序设计6 分钟前
救命!Java 进阶居然还在考这些“小儿科”?
java·前端
总是学不会.12 分钟前
【JUC编程】多线程学习大纲
java·后端·开发
MediaTea14 分钟前
思考与练习(第十章 文件与数据格式化)
java·linux·服务器·前端·javascript
Matlab光学20 分钟前
MATLAB仿真:离轴干涉法实现光学全息加密与解密
开发语言·matlab
7澄120 分钟前
Maven 项目拆分与聚合实战:分层架构下的多模块开发
java·架构·maven·service·dao·pojo·数据库连接
一起养小猫26 分钟前
LeetCode100天Day4-盛最多水的容器与两数之和II
java·数据结构·算法·leetcode
小鸡吃米…29 分钟前
Python - JSON
开发语言·python·json
ZBritney31 分钟前
JAVA中的多线程
java
JAVA+C语言34 分钟前
C#——接口
开发语言·c#