news 2026/5/11 4:27:14

深入解析AQS:Java并发基石

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入解析AQS:Java并发基石

🔑 一、AQS 是什么?——“同步器的骨架”

AQS = AbstractQueuedSynchronizer
它是一个抽象类,提供了一套基于 FIFO 阻塞队列 + 原子状态管理的框架,让你能轻松实现各种自定义的同步工具。

✅ 核心能力:

  1. 管理一个整型状态(state:表示资源是否可用(如锁是否被占用、计数器剩余值等)。
  2. 维护一个 FIFO 等待队列:当线程获取资源失败时,自动入队并阻塞;释放资源时,唤醒队列中的下一个线程。
  3. 支持独占模式(exclusive)和共享模式(shared)
    • 独占:同一时刻只能一个线程持有(如ReentrantLock)。
    • 共享:多个线程可同时持有(如SemaphoreCountDownLatch)。

💡AQS 本身不定义“同步语义”,而是把“如何判断能否获取资源”、“如何释放资源”这些逻辑留给子类实现


🧱 二、AQS 的核心机制

1.状态管理(State)

  • 通过volatile int state表示同步状态。
  • 提供三个方法操作它:
    protectedfinalintgetState()protectedfinalvoidsetState(intnewState)protectedfinalbooleancompareAndSetState(intexpect,intupdate)// CAS
  • 子类通过这个state来表达自己的业务含义:
    • ReentrantLock:0=未锁,1=已锁(重入次数)
    • Semaphore:表示剩余许可数量
    • CountDownLatch:表示倒计数值

2.FIFO 等待队列(CLH 变种)

AQS 使用一个双向链表(Node 链表)来管理等待线程:

head → [Node1] ↔ [Node2] ↔ [Node3] ← tail

每个Node包含:

  • thread:等待的线程
  • waitStatus:节点状态(如SIGNAL=-1表示需要被唤醒)
  • prev/next:前后指针
  • nextWaiter:用于区分是独占还是共享模式(或用于 Condition)

⚠️ 注意:这是一个CLH 队列的变种,原始 CLH 用于自旋锁,而 AQS 用于阻塞锁,所以增加了next指针便于唤醒后继。


3.两种模式:独占 vs 共享

模式方法说明
独占(Exclusive)tryAcquire()
tryRelease()
成功则获得排他权限(如写锁)
共享(Shared)tryAcquireShared()
tryReleaseShared()
返回值 ≥0 表示成功,可多线程并发(如读锁、信号量)

🔄 共享模式下,释放资源时可能级联唤醒多个线程(因为多个线程可能同时满足条件)。


🧩 三、关键流程解析

▶ 获取资源(以独占为例)

publicfinalvoidacquire(intarg){if(!tryAcquire(arg)&&acquireQueued(addWaiter(Node.EXCLUSIVE),arg))selfInterrupt();}
  1. 先尝试tryAcquire()(由子类实现)。
  2. 如果失败,调用addWaiter()将当前线程封装成Node加入队尾。
  3. 调用acquireQueued():在队列中自旋,直到被前驱唤醒且自己成为头节点后再次尝试获取。

▶ 释放资源(独占)

publicfinalbooleanrelease(intarg){if(tryRelease(arg)){// 子类实现Nodeh=head;if(h!=null&&h.waitStatus!=0)unparkSuccessor(h);// 唤醒后继returntrue;}returnfalse;}
  • 成功释放后,调用unparkSuccessor()唤醒下一个等待线程。

🔍unparkSuccessor()会从tail往前找第一个非取消的节点(处理中间节点被中断/超时的情况)。


🛠️ 四、如何使用 AQS?——子类必须实现的方法

不能直接使用 AQS,而是继承它并实现以下方法(根据需求选):

方法用途必须实现?
tryAcquire(int)独占式获取是(如果支持独占)
tryRelease(int)独占式释放
tryAcquireShared(int)共享式获取是(如果支持共享)
tryReleaseShared(int)共享式释放
isHeldExclusively()当前线程是否独占持有是(如果要用Condition

✅ 所有这些方法都必须是无阻塞、线程安全、短小精悍的!


📌 五、经典例子回顾

例1:非重入互斥锁(Mutex)

staticclassSyncextendsAbstractQueuedSynchronizer{protectedbooleantryAcquire(intacquires){if(compareAndSetState(0,1)){setExclusiveOwnerThread(Thread.currentThread());returntrue;}returnfalse;}protectedbooleantryRelease(intreleases){setState(0);setExclusiveOwnerThread(null);returntrue;}protectedbooleanisHeldExclusively(){returngetState()==1;}}

例2:一次性门闩(BooleanLatch)

staticclassSyncextendsAbstractQueuedSynchronizer{protectedinttryAcquireShared(intignore){returngetState()==1?1:-1;// 1=已触发,-1=需等待}protectedbooleantryReleaseShared(intignore){setState(1);returntrue;// 唤醒所有等待者}}

🌟 六、高级特性

1.公平性控制

  • 默认是非公平的(允许“插队”:新线程可能在排队线程之前抢到锁)。
  • 实现公平锁:在tryAcquire中加判断:
    if(hasQueuedPredecessors())returnfalse;// 有排队者就别插队

2.Condition 支持

  • 通过new ConditionObject()创建条件变量。
  • 必须实现isHeldExclusively()和正确的release/acquire逻辑。

3.可中断、超时支持

  • AQS 提供了acquireInterruptiblytryAcquireNanos等方法,子类只需调用即可。

✅ 总结:AQS 的设计哲学

“Don’t call us, we’ll call you.” — Hollywood Principle

  • AQS 负责:队列管理、线程阻塞/唤醒、状态原子性、中断/超时处理
  • 你(子类)负责:定义“什么是获取成功”、“什么是释放成功”

这使得你可以用几十行代码实现出工业级的同步器,而无需操心底层并发细节。


如果你正在学习 JUC 或想深入理解ReentrantLockSemaphore等的原理,掌握 AQS 是必经之路。它的设计堪称 Java 并发编程的“皇冠上的明珠”。

如需进一步分析某个具体同步器(比如ReentrantReadWriteLock如何用 AQS 实现读写锁),欢迎继续提问!

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

GLM-TTS与Figma无关?但UI设计同样重要!

GLM-TTS:让声音克隆变得简单,但别忽视交互设计的力量 在虚拟主播一夜爆红、AI有声书批量生成的今天,个性化语音合成早已不再是实验室里的概念。真正让人兴奋的是,我们只需要几秒钟的录音,就能让机器“学会”一个人的声…

作者头像 李华
网站建设 2026/5/11 2:49:17

P值校正:Bonferroni与Benjamini-Hochberg方法详解

Bonferroni与Benjamini-Hochberg:选择你的P值校正方法 P值可能是一个敏感的话题。或许初次与统计学家接触时最好避免讨论它。对这个话题的态度导致大家默认α 0.05是黄金标准——实际上,这只是罗纳德费舍尔本人设定的一个“方便的惯例”,一个…

作者头像 李华
网站建设 2026/5/10 5:14:39

如何用GLM-TTS生成在线考试听力材料自动化命题

如何用GLM-TTS生成在线考试听力材料自动化命题 在一场全国性英语等级考试的命题现场,以往需要数名录音员反复录制、剪辑、校对整整三天才能完成的听力音频,如今只需一位教师提供一段8秒的朗读样本,配合一个自动化脚本——不到两小时&#xff…

作者头像 李华
网站建设 2026/5/10 14:10:50

如何用GLM-TTS生成企业培训资料语音版提升学习效果

如何用GLM-TTS生成企业培训资料语音版提升学习效果 在快节奏的企业环境中,员工的学习时间越来越碎片化。通勤路上、午休间隙、出差途中——这些原本被忽略的时间窗口,正成为知识吸收的新战场。然而,传统的培训文档多以文字或视频形式存在&…

作者头像 李华
网站建设 2026/5/10 13:07:51

GLM-TTS官方文档之外的知识补充:社区经验精华整理

GLM-TTS实战精要:从社区经验看方言克隆、发音控制与情感表达 在语音合成技术快速演进的今天,一个真正好用的TTS系统不仅要“能说话”,更要“说对话”、“说准话”、“说动人”。GLM-TTS作为近年来开源社区中备受关注的端到端文本到语音模型&…

作者头像 李华