news 2026/3/7 18:32:10

【Java进阶】深度解密 AQS:Java 并发包背后的“灵魂骨架”

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Java进阶】深度解密 AQS:Java 并发包背后的“灵魂骨架”

🍂枫言枫语:我是予枫,一名行走在 Java 后端与多模态 AI 交叉路口的研二学生。

“予一人以深耕,观万木之成枫。”

在这里,我记录从底层源码到算法前沿的每一次思考。希望能与你一起,在逻辑的丛林中寻找技术的微光。

在 Java 面试或者研读源码时,你一定会被问到:ReentrantLock是怎么实现的?CountDownLatch为什么能让线程等待?这些看似功能迥异的组件,其实背后都指向了同一个名字——AQS

今天,我来带大家拆解这个 Doug Lea 大神留下的神作。


一、 AQS 到底是什么?

AQS,全称AbstractQueuedSynchronizer(抽象队列同步器)。

简单来说,它是一个框架。它把实现一个锁(或同步器)最繁琐的工作(比如线程排队、线程阻塞与唤醒、CAS 操作状态等)全部封装好了。你只需要在这个框架的基础上,填入一点点关于“如何获取锁”和“如何释放锁”的业务逻辑,就能造出一把功能完备的锁。

形象比喻:自动化的银行柜台

想象一个只有一个柜台的银行:

  • State(状态):柜台是否有人(0 表示空闲,1 表示有人)。

  • CAS:客户尝试冲向柜台的动作。

  • CLH 队列:没抢到柜台的人,自觉去排队。

  • AQS 框架:银行的自动排队机和叫号系统。它负责维护队列,并在柜台空闲时,叫醒下一个人。


二、 AQS 的“三大支柱”

要理解 AQS,必须死磕这三个核心组成部分:

1. 状态位:volatile int state

这是 AQS 的核心。所有的同步状态都靠它。

  • ReentrantLock中,state表示锁的持有次数(0 为空闲,1 为被占用,>1 为重入次数)。

  • Semaphore中,state表示剩余的可用许可数。

  • CountDownLatch中,state表示还需要等待的计数。

注意:state是被volatile修饰的,保证了多线程下的可见性。

2. CAS (Compare And Swap)

AQS 频繁使用 CAS 指令来修改state的值。这是实现“无锁化”或“轻量级锁”的关键。只有 CAS 成功的线程,才算真正拿到了锁。

3. CLH 变体队列(双向链表)

当线程抢锁失败时,AQS 会将其封装成一个Node节点,并放入一个双向链表中。

  • 头节点 (Head):正在持有锁的那个线程。

  • 后续节点:正在苦苦等待被唤醒的线程。


三、 AQS 的两种工作模式

AQS 设计最精妙的地方在于它同时支持两种模式:

  1. 独占模式 (Exclusive):

    一次只能有一个线程持有锁。如 ReentrantLock。

  2. 共享模式 (Shared):

    允许多个线程同时获取。如 Semaphore(信号量)、ReadLock(读锁)、CountDownLatch。

这种“一套框架,两样通吃”的设计,体现了极高的抽象能力。


四、 源码级流程:一个线程的“抢锁之旅”

我们以ReentrantLock.lock()为例,看看 AQS 内部发生了什么:

第一步:acquire(1)

线程尝试获取锁。

  • 调用tryAcquire(1)。这个方法是由具体的子类(如NonfairSync)实现的。

  • 如果成功(CAS 修改 state 从 0 变 1 成功),直接开干。

第二步:addWaiter(Node.EXCLUSIVE)

如果tryAcquire失败了,AQS 会把当前线程包装成一个Node,塞进队列的尾部。这里用到了“自旋 + CAS”来保证线程安全地入队。

第三步:acquireQueued(node, 1)

这是最精彩的部分。线程入队后不会立即睡觉(挂起),而是会再看一眼:“我的前驱节点是不是头节点?”

  • 如果是,说明快轮到我了,再试一次tryAcquire

  • 如果不是,或者再次尝试也失败了,那就调用LockSupport.park(this),心安理得地阻塞休眠


五、 为什么 AQS 这么快?

  1. 自旋优化:线程在进入阻塞状态前,会进行少量的自旋尝试,减少了内核态和用户态切换的开销。

  2. 双向链表:便于取消某个排队节点(比如等待超时的线程),只需要修改前后指针即可。

  3. 模板方法模式:AQS 定义了骨架,复杂的线程调度逻辑由 AQS 处理,子类只需关心简单的状态修改逻辑。


六、 给“予枫”读者的总结

AQS 的精髓在于:它通过一个volatile状态位和一个高效的 FIFO 队列,完美地解决了多线程抢占资源的冲突问题。

如果你在准备面试,记住这几个关键词:volatile stateCAS双向 CLH 队列LockSupport


下一步建议

单纯看博文是不够的。建议你打开 IntelliJ IDEA,输入ReentrantLock,顺着lock()方法点进去,看看那个叫Sync的内部类,你会发现它真的继承了AbstractQueuedSynchronizer

关于作者: 💡予枫,某高校在读研究生,专注于 Java 后端开发与多模态情感计算。💬欢迎点赞、收藏、评论,你的反馈是我持续输出的最大动力!

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:

https://cloud.tencent.com/developer/support-plan?invite_code=9wrxwtlju1l

当前加入还有惊喜相送!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 7:36:52

使用qthread实现后台数据采集实战

如何用 QThread 打造流畅的后台数据采集系统?实战避坑全解析你有没有遇到过这样的场景:点击“开始采集”按钮后,界面瞬间卡住,鼠标拖不动、按钮点不灵,几秒甚至十几秒后才突然刷新一堆数据——用户以为程序崩溃了&…

作者头像 李华
网站建设 2026/3/4 11:08:57

AI舞蹈动作捕捉:MediaPipe Pose实战教程

AI舞蹈动作捕捉:MediaPipe Pose实战教程 1. 引言:AI人体骨骼关键点检测的现实价值 在虚拟偶像、智能健身、远程教学和AI舞蹈生成等前沿应用中,人体姿态估计(Human Pose Estimation)正成为核心技术支撑。通过从普通RG…

作者头像 李华
网站建设 2026/3/7 6:28:57

YOLOv8目标检测避坑指南:工业场景常见问题全解

YOLOv8目标检测避坑指南:工业场景常见问题全解 1. 引言:工业级YOLOv8的挑战与价值 在智能制造、智能安防、仓储物流等工业场景中,目标检测模型不仅要“看得准”,更要“跑得稳”。基于Ultralytics YOLOv8构建的“鹰眼目标检测”镜…

作者头像 李华
网站建设 2026/3/3 20:09:11

实测YOLOv8鹰眼检测:无人机巡航电动车违规行为效果惊艳

实测YOLOv8鹰眼检测:无人机巡航电动车违规行为效果惊艳 1. 背景与挑战:电动自行车监管的智能化转型 近年来,电动自行车已成为我国城市和乡村居民出行的重要交通工具。其轻便、灵活、经济的特点使其保有量持续攀升。然而,随之而来…

作者头像 李华
网站建设 2026/3/4 6:32:36

使用NX二次开发构建标准件库:零基础指南

从零打造专属标准件库:NX二次开发实战全解析你是否曾为反复建模一个M8螺栓而感到厌烦?是否遇到过团队中不同工程师画出的“标准件”尺寸不一、命名混乱,导致装配出错、BOM统计困难?在项目周期越来越紧的今天,这些看似微…

作者头像 李华
网站建设 2026/3/4 1:43:42

CH340驱动安装过程中设备管理器异常处理指南

CH340驱动装不上?设备管理器报错终极排查指南 你有没有遇到过这样的场景:手握一块Arduino开发板、STM32下载器或者ESP32模块,信心满满地插上USB线准备烧录程序,结果打开设备管理器一看—— “未知设备”、“代码10错误”、“COM…

作者头像 李华