news 2026/11/5 9:08:48

AQS共享锁的传播机制精髓

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AQS共享锁的传播机制精髓

一、背景:共享模式 vs 独占模式

  • 独占模式(Exclusive):如ReentrantLock,一次只允许一个线程持有锁。
    • 释放时:只需唤醒队列中的下一个等待者(调用unparkSuccessor(head)即可)。
  • 共享模式(Shared):如Semaphore、CountDownLatch、ReadWriteLock的读锁。
    • 允许多个线程同时持有锁(只要资源足够)。
    • 所以:一旦资源可用,可能要连续唤醒多个等待线程!

这就引出了“传播(propagation)”的概念。


二、核心问题:如何确保“所有能获取资源的线程都被唤醒”?

假设:

  • 当前有 3 个线程在 AQS 队列中等待共享锁(A → B → C)。
  • 此时资源释放了(比如信号量 permit +1)。
  • 线程 A 被唤醒并成功获取资源。
  • 但此时资源仍然充足(比如 permit 还剩 1),那么 B 也应该被唤醒!

但如果只在释放时唤醒一次(像独占锁那样),B 和 C 就可能永远等下去,即使资源已经可用。

👉 因此,共享模式必须支持“级联唤醒”或“传播唤醒”。


三、PROPAGATE 和 SIGNAL 的作用

🔹Node.SIGNAL(-1)

  • 含义:当前节点的后继节点需要被唤醒。
  • 这是 AQS 中通用的状态,独占和共享都用。
  • 当一个节点入队后,会把前驱设为SIGNAL,表示“我等着,你释放时记得叫我”。

🔹Node.PROPAGATE(-3)

  • 仅用于共享模式。
  • 含义:即使当前没有明确的“需要唤醒”的信号,也要继续传播释放动作。
  • 它是一种“保险机制”,防止在并发竞争下漏掉唤醒。

四、为什么需要 PROPAGATE?—— 并发场景下的“信号丢失”问题

考虑这个竞态条件(race condition):

  1. 线程 T1 调用releaseShared(),准备唤醒后继。
  2. 此时队列 head 是 H,H 的 waitStatus 是 0(因为刚被设置为 head,还没来得及设 SIGNAL)。
  3. T1 检查到ws == 0,于是尝试 CAS 把它设为PROPAGATE(表示:“虽然现在没信号,但我要记录这次释放,以便后续传播”)。
  4. 与此同时,另一个线程 T2 成功获取了共享锁,并调用setHeadAndPropagate,把新节点设为 head。
  5. 如果没有PROPAGATE,T1 可能认为“没人需要唤醒”,直接退出,导致后面的线程无法被唤醒!

✅PROPAGATE的作用就是:在状态不确定时,留下一个“释放发生过”的标记,确保后续操作能继续传播唤醒。


五、代码逻辑精解

setHeadAndPropagate(node, propagate)

  • propagate > 0:表示tryAcquireShared返回正数,说明还有剩余资源,应该继续唤醒别人。
  • 条件判断很“保守”(conservative):
    if(propagate>0||h==null||h.waitStatus<0||...)
    只要有任何迹象表明可能需要传播,就调用doReleaseShared()。
  • 特别注意:h.waitStatus < 0包括SIGNAL(-1)和PROPAGATE(-3),都表示“需要关注后继”。

doReleaseShared()

这是一个自旋 + CAS 的传播循环:

for(;;){Nodeh=head;if(h!=null&&h!=tail){intws=h.waitStatus;if(ws==SIGNAL){// 正常情况:后继需要唤醒CAS(SIGNAL→0);unparkSuccessor(h);}elseif(ws==0){// 没有明确信号,但可能是并发释放!// 设为 PROPAGATE,留下“释放已发生”的标记CAS(0→PROPAGATE);}}// 如果 head 没变,说明稳定了,可以退出if(h==head)break;}

💡 关键思想:即使当前看不出需要唤醒谁,也要通过 PROPAGATE 确保“释放事件”不会丢失。


六、举个实际例子:Semaphore

Semaphoresem=newSemaphore(1);// 三个线程同时调用 sem.acquire()// 初始 permit = 1,只有第一个能成功,其他两个入队等待。sem.release();// permit 变回 1
  • release()→ 调用releaseShared()→doReleaseShared()
  • 唤醒第一个等待线程(A)
  • A 获取 permit 后,发现propagate = 0(因为 permit 用完了),不传播
  • 但如果release()被调用了两次(permit=2),则:
    • 第一次唤醒 A,A 获取后 permit=1 →propagate=1→ 继续传播
    • 触发第二次doReleaseShared(),唤醒 B

如果没有传播机制,B 就卡住了!


七、总结:精髓所在

概念作用
传播(Propagation)共享模式下,一次释放可能需唤醒多个线程
SIGNAL (-1)明确指示“后继需要唤醒”
PROPAGATE (-3)在状态模糊时,防止释放信号丢失的保险机制
自旋 + CAS 循环应对高并发下的状态竞争,确保最终一致性

✅设计哲学:
“宁可多唤醒几次(unnecessary wake-ups),也不能漏掉一次该唤醒的线程。”
—— 这就是 AQS 共享模式的鲁棒性所在。


附加:Node.waitStatus 的几个值

值常量含义
0—初始状态
-1SIGNAL后继需要被唤醒
-2CONDITION在 Condition 队列中
-3PROPAGATE共享模式下,表示应继续传播释放
1CANCELLED节点已取消

希望这能帮你彻底理解 AQS 共享模式的“传播”机制!

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

GLM-4.6V-Flash-WEB与ComfyUI结合:打造智能视觉工作流

GLM-4.6V-Flash-WEB与ComfyUI结合&#xff1a;打造智能视觉工作流 在今天的内容审核、图像理解与自动化决策场景中&#xff0c;企业越来越依赖能够“看懂图”的AI系统。然而&#xff0c;现实却常常令人沮丧——许多视觉大模型虽然准确率高&#xff0c;但部署复杂、响应迟缓&…

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

ComfyUI节点连线错误排查:GLM-4.6V-Flash-WEB输入输出匹配

ComfyUI节点连线错误排查&#xff1a;GLM-4.6V-Flash-WEB输入输出匹配 在构建多模态AI应用的过程中&#xff0c;越来越多开发者选择使用 ComfyUI 这类图形化流程编排工具来快速搭建视觉语言模型的工作流。其直观的节点式操作极大降低了开发门槛&#xff0c;尤其适合需要频繁调试…

作者头像 李华
网站建设 2026/11/3 1:55:34

GitHub镜像网站Gitee同步GLM-4.6V-Flash-WEB项目仓库

GLM-4.6V-Flash-WEB&#xff1a;轻量级多模态模型的国产化落地实践 在智能应用日益渗透日常生活的今天&#xff0c;用户对“看图说话”式交互的期待已不再局限于科技演示——他们希望上传一张发票就能自动提取信息&#xff0c;拍下一道数学题就能获得解题思路&#xff0c;甚至用…

作者头像 李华
网站建设 2026/11/3 1:55:34

GLM-4.6V-Flash-WEB部署全攻略:单卡推理实现高效多模态应用

GLM-4.6V-Flash-WEB部署全攻略&#xff1a;单卡推理实现高效多模态应用 在智能客服、电商图文理解、教育辅助系统等实际场景中&#xff0c;用户早已不再满足于“只能看图”或“只会读字”的AI模型。他们需要的是一个能快速理解图像内容&#xff0c;并用自然语言流畅回应的助手—…

作者头像 李华
网站建设 2026/11/4 23:49:32

调试Dify插件总失败?你可能忽略了这4个关键细节

第一章&#xff1a;调试Dify插件总失败&#xff1f;先理清核心逻辑在开发和集成Dify插件时&#xff0c;频繁的调试失败往往源于对系统核心逻辑的理解偏差。Dify作为一个低代码AI应用开发平台&#xff0c;其插件机制依赖于清晰的输入输出契约与运行时上下文管理。若未准确把握这…

作者头像 李华
网站建设 2026/11/3 8:45:46

深度剖析Dify性能瓶颈:GPU/内存/IO资源利用率翻倍技巧

第一章&#xff1a;Dify私有化部署性能优化概述在企业级AI应用中&#xff0c;Dify的私有化部署已成为保障数据安全与系统可控的核心方案。然而&#xff0c;随着业务规模扩大和并发请求增长&#xff0c;系统性能可能面临响应延迟、资源瓶颈等问题。因此&#xff0c;对Dify进行性…

作者头像 李华