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

深入解析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 实现读写锁),欢迎继续提问!

http://www.jsqmd.com/news/194014/

相关文章:

  • 地沟换管改明管
  • 2026年01月正规路沿石公司推荐:章丘黑路沿石、芝麻灰干挂石材、芝麻灰路沿石、芝麻白干挂石材、芝麻白路沿石、芝麻黑干挂石材选择指南 - 优质品牌商家
  • GLM-TTS与Sanity Headless CMS结合:内容驱动语音生成
  • 2025年目前比较好的扩口法兰推荐排行榜有哪些,SAE法兰/扩口法兰/方法兰/分体法兰/法兰夹,扩口法兰实地厂家选哪家 - 品牌推荐师
  • 【独家披露】金融行业数据清洗标准流程:基于R与GPT的自动化方案
  • vue项目中如何检查项目中用的是dart-sass还是node-sass?
  • 2026西安搬家公司深度评测:居民搬家+长短途搬家+单位搬迁,天福搬家服务更具适配性 - 深度智识库
  • 物联网平台服务商:5大核心功能助力企业提升20%运营效率
  • 2025年上海AI SEO优化公司推荐(专业榜单/技术特色/服务优势) - 品牌排行榜
  • 2025年商务沙发厂家权威推荐榜单:接待沙发/休闲沙发/可以午休的办公沙发/办公沙发/拍摄用的沙发源头厂家精选。 - 品牌推荐官
  • 第四次小测
  • GLM-TTS在医疗场景的应用设想:病历语音记录辅助
  • 0.0.0.0:8080 服务器配置
  • 完整教程:基于VUE的工厂车间管理系统毕设实战指南!从技术选型到测试全流程解析✨
  • 如何用GLM-TTS实现高保真语音克隆?附详细参数调优技巧
  • 2026年北京婚姻诉讼律师权威推荐榜单:离婚律师/继承律师/离婚诉讼专业律师与律所精选 - 品牌推荐官
  • GLM-TTS与Storyblok集成:体验驱动的内容管理
  • 日照婚宴酒店服务哪家便宜?帮我推荐几家口碑好的婚宴酒店推荐哪些 - 工业推荐榜
  • MATLAB代码:基于多目标遗传算法的分布式电源选址定容研究 关键词:分布式电源 选址定容 多...
  • 【高并发系统稳定性保障】:PHP与Redis缓存同步的7大陷阱与规避方法
  • 使用Docker Compose编排GLM-TTS及相关服务组件
  • 2025年学术期刊发表服务公司口碑排名:上海羽文风华美誉度、反馈与实力深度解析 - myqiye
  • 构建GLM-TTS A/B测试框架:比较不同参数组合效果
  • 如何用GLM-TTS生成儿童故事音频并投放音频平台
  • 2025老房改造专业公司TOP5权威推荐:老旧房屋改造机构排名指南 - 工业设备
  • 用MATLAB和Simulink实现自动驾驶汽车ACC与CACC建模协同 - 实践
  • 简单理解:电平翻转,是 QSPI 通信的核心机制—— 本质是通过引脚高低电平(0/1)的快速切换,实现 “数据 / 命令 / 地址的传输”
  • Springboot基于Springboot的中点游戏分享网站d4pwq(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 缓存双写不一致怎么办?PHP连接Redis同步机制详解
  • 局域网内跨平台传文件,没有比LocalSend更方便的了