当前位置: 首页 > news >正文

深入理解 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 管理。在这里插入图片描述
很好的抽象,该交给子类去扩展的就封装抽象方法,让子类决定是否支持共享模式在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


文章转载自:

http://wRSf0STU.qbgff.cn
http://bpI9UUZi.qbgff.cn
http://Iwd6j7gC.qbgff.cn
http://Z7N2DfRc.qbgff.cn
http://WlrgYHie.qbgff.cn
http://7eUTw7Om.qbgff.cn
http://pR3T30AR.qbgff.cn
http://GQi4Nu0Z.qbgff.cn
http://bF6GPT4H.qbgff.cn
http://7Vslct64.qbgff.cn
http://GkgKt6dx.qbgff.cn
http://rMZrBBqr.qbgff.cn
http://xO6nvNEA.qbgff.cn
http://T2IlMhoE.qbgff.cn
http://HhXl0hTe.qbgff.cn
http://6Cad7rpQ.qbgff.cn
http://d84wYdww.qbgff.cn
http://apvOR8TZ.qbgff.cn
http://ponxtl8d.qbgff.cn
http://jcgfke2e.qbgff.cn
http://UrHE5ehz.qbgff.cn
http://jAYV0xLL.qbgff.cn
http://qs8gucGF.qbgff.cn
http://T2raZmUh.qbgff.cn
http://Pi6VBpQH.qbgff.cn
http://sc4y8lBE.qbgff.cn
http://jwC6SEoo.qbgff.cn
http://PvE4XSCo.qbgff.cn
http://lxkM0tOn.qbgff.cn
http://3WiZOxOQ.qbgff.cn
http://www.dtcms.com/a/374268.html

相关文章:

  • 32位CPU架构是如何完成两数(32位)相加的指令的?
  • 深度学习中的损失函数都有哪些,大模型时代主要用的损失函数有哪些,中间有什么区别?
  • java:io流相关类的继承关系梳理
  • PAT 1004 Counting Leaves
  • Linux操作系统shell脚本语言-第六章
  • 基于Springboot + vue3实现的小区物业管理系统
  • 自动化测试DroidRun
  • 把一段 JSON 字符串还原成一个实体对象
  • YOLO系列论文梳理(AI版)
  • ARM内核知识概念
  • 图论相关经典题目练习及详解
  • 深圳比斯特|多维度分选:圆柱电池品质管控的自动化解决方案
  • MySQL 日志全解析:Binlog/Redo/Undo 等 5 类关键日志的配置、作用与最佳实践
  • 龙虎榜——20250908
  • 自噬机制解析(二):一文厘清 LC3/Atg8 概念及实验应用要点
  • java类加载过程
  • 20250908-02:运行第一个 LLM 调用程序
  • 基于A2A和ADK的内容规划代理
  • 电流源电路
  • 随机获取数组内任意元素
  • ESNP LAB 笔记:配置MPLS(Part4)
  • 发布工业智能体,云从科技打造制造业AI“运营大脑”
  • Flask 博客系统(Flask Blog System)
  • Qt_UI界面的设计
  • pycharm 最新版上一次编辑位置
  • 【Pywinauto库】1. 3 Inspect.exe 使用详解指南
  • 「日拱一码」083 深度学习——残差网络
  • 注意力模块改进方法的原理及实现(MHA、MQA、GQA、MLA)
  • 蚂蚁 S21 Pro 220T矿机参数详解:SHA-256算法高效算力分析
  • 大模型测试包含哪些方面