独占锁和共享锁唤醒机制

news/2025/12/9 20:23:06/文章来源:https://www.cnblogs.com/hellodeyang/p/19328280

目录
  • 独占锁和共享锁唤醒机制
    • 精确总结
      • 独占锁(EXCLUSIVE)
      • 共享锁(SHARED)
    • 独占锁的正确顺序:
    • 共享锁的正确顺序:
    • 核心区别可视化
      • 独占锁(接力赛)
      • 共享锁(广播链)
    • 代码验证
    • 关键区别表格
    • 总结

独占锁和共享锁唤醒机制

精确总结

独占锁(EXCLUSIVE)

// 释放时:unlock() → release() → unparkSuccessor()
// 只唤醒队列中的第一个有效后继节点
// 唤醒后整个释放过程就结束了

特点

  • 一次释放,只唤醒一个线程
  • 被唤醒的线程获取锁后不会主动唤醒其他线程
  • 唤醒链不传播

共享锁(SHARED)

// 释放时:releaseShared() → doReleaseShared()
// 1. 先唤醒第一个后继节点
// 2. 被唤醒的线程在返回前,会调用setHeadAndPropagate()
// 3. setHeadAndPropagate()中会再次调用doReleaseShared()唤醒下一个
// 4. 形成唤醒链,直到没有需要唤醒的节点

特点

  • 一次释放,触发连锁唤醒
  • 被唤醒的线程会"接力"唤醒下一个
  • 唤醒链会一直传播

独占锁的正确顺序:

初始:线程1、2、3都在等待队列中head → 线程1 → 线程2 → 线程3 → tail1. 释放锁 → unparkSuccessor(head) → 唤醒线程1
2. 线程1被唤醒 → 获取锁 → 执行任务
3. 线程1执行完毕 → unlock() → 再次unparkSuccessor() → 唤醒线程2
4. 线程2被唤醒 → 获取锁 → 执行任务
5. 线程2执行完毕 → unlock() → 唤醒线程3
6. 线程3被唤醒 → 获取锁 → 执行任务关键:执行和唤醒是串行的,一个线程执行完才唤醒下一个

共享锁的正确顺序:

初始:线程1、2、3都在等待队列中  head → 线程1 → 线程2 → 线程3 → tail1. 释放资源 → doReleaseShared() → unparkSuccessor(head) → 唤醒线程1
2. 线程1被唤醒 → 获取共享资源 → 立即调用setHeadAndPropagate()
3. setHeadAndPropagate()中调用doReleaseShared() → 唤醒线程2
4. 线程2被唤醒 → 获取共享资源 → 立即调用setHeadAndPropagate()  
5. setHeadAndPropagate()中调用doReleaseShared() → 唤醒线程3
6. 线程3被唤醒 → 获取共享资源 → ...
7. 所有线程几乎同时开始执行(如果资源足够)关键:唤醒是链式、立即的,可能所有线程都被唤醒后才开始执行任务

核心区别可视化

独占:唤醒1 → [线程1执行] → 唤醒2 → [线程2执行] → 唤醒3 → [线程3执行]↑                     ↑                     ↑执行和唤醒严格交替      执行完才唤醒下一个       串行执行共享:唤醒1 → 唤醒2 → 唤醒3 → [线程1、2、3几乎同时开始执行]↑        ↑        ↑快速链式唤醒      不需要等待前一个执行完      并行/并发执行

独占锁(接力赛)

// 像接力棒,必须一个接一个
┌─────────┐    ┌─────────┐    ┌─────────┐
│ 唤醒线程1 │──→│线程1执行│──→│ 唤醒线程2 │──→│线程2执行│──→│ 唤醒线程3 │
└─────────┘    └─────────┘    └─────────┘    └─────────┘    └─────────┘时间:t1         t2            t3            t4            t5

共享锁(广播链)

// 像多米诺骨牌,快速连续触发
┌─────────┐    ┌─────────┐    ┌─────────┐
│ 唤醒线程1 │──→│ 唤醒线程2 │──→│ 唤醒线程3 │
└─────────┘    └─────────┘    └─────────┘│             │             │↓             ↓             ↓
┌─────────┐    ┌─────────┐    ┌─────────┐
│线程1执行│    │线程2执行│    │线程3执行│    ← 几乎同时开始
└─────────┘    └─────────┘    └─────────┘时间:t2         t2           t2      (时间很接近)

代码验证

public class WakeupTimingDemo {static long startTime;public static void main(String[] args) throws InterruptedException {System.out.println("=== 测试独占锁唤醒时序 ===");testExclusiveTiming();Thread.sleep(1000);System.out.println("\n=== 测试共享锁唤醒时序 ===");testSharedTiming();}static void testExclusiveTiming() throws InterruptedException {ReentrantLock lock = new ReentrantLock();startTime = System.currentTimeMillis();// 主线程先获取锁lock.lock();// 创建3个线程for (int i = 1; i <= 3; i++) {final int id = i;new Thread(() -> {lock.lock();  // 等待锁try {long time = System.currentTimeMillis() - startTime;System.out.printf("  线程%d 在 %dms 后获得锁,执行1秒\n", id, time);Thread.sleep(1000);  // 模拟任务执行} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}).start();}Thread.sleep(100);System.out.println("主线程在 100ms 释放锁");lock.unlock();  // 释放锁,开始唤醒链Thread.sleep(5000);}static void testSharedTiming() throws InterruptedException {Semaphore semaphore = new Semaphore(0);  // 0个许可,所有线程都会阻塞startTime = System.currentTimeMillis();// 创建3个线程for (int i = 1; i <= 3; i++) {final int id = i;new Thread(() -> {try {semaphore.acquire();  // 等待许可long time = System.currentTimeMillis() - startTime;System.out.printf("  线程%d 在 %dms 后被唤醒,执行1秒\n", id, time);Thread.sleep(1000);  // 模拟任务执行} catch (InterruptedException e) {e.printStackTrace();}}).start();}Thread.sleep(100);System.out.println("主线程在 100ms 释放1个许可");semaphore.release(3);  // 释放3个许可,会链式唤醒Thread.sleep(5000);}
}

可能的输出

=== 测试独占锁唤醒时序 ===
主线程在 100ms 释放锁线程1 在 100ms 后获得锁,执行1秒线程2 在 1100ms 后获得锁,执行1秒  ← 注意:线程1执行完才唤醒线程2线程3 在 2100ms 后获得锁,执行1秒  ← 线程2执行完才唤醒线程3=== 测试共享锁唤醒时序 ===  
主线程在 100ms 释放1个许可线程1 在 100ms 后被唤醒,执行1秒线程2 在 101ms 后被唤醒,执行1秒  ← 几乎同时被唤醒!线程3 在 102ms 后被唤醒,执行1秒  ← 几乎同时被唤醒!

关键区别表格

对比项 独占锁 共享锁
唤醒时机 前一个线程执行完后才唤醒下一个 立即链式唤醒,不管前一个是否开始执行
执行时机 严格串行,一个接一个 可能并发执行,特别是资源足够时
唤醒链 执行完才传递"唤醒权" 唤醒时就传递"唤醒权"
性能影响 延迟大,吞吐量低 延迟小,吞吐量高

总结

时间顺序:

  1. 独占锁是"执行-唤醒-执行-唤醒"的串行模式
  2. 共享锁是"唤醒-唤醒-唤醒-执行"的快速传播模式

这也是为什么共享锁(如Semaphore)适合高并发场景的原因:它能快速唤醒大量等待线程,提高系统吞吐量。而独占锁(如ReentrantLock)则更注重互斥性和公平性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/995504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

个人学习---25.12.9

markdown简单学习这是我markdown的开始,我将把他作为我的ysyx笔记 markdon记录标题使用就表示几级几级,很简单不多说文本格式 ####### 斜体文本 粗体文本 粗斜体文本 分隔线 可以使用---来表示代码块int main6(void)…

大模型完整架构

后端模型:利用ollama平台模型 前端界面:利用streamlit框架搭建用户界面,streamlit是一个简单易用的python库 对话交互:用户通过strealit界面输入文本,聊天机器人基于模型对输入内容处理并恢复展示在界面上 模型调…

iOS 知识点 - 一篇文章带你串通「操作系统 内存模型 文件系统」

本文重点讲解 iOS 操作系统,Linux/Windows 操作系统待到后续新开文章专门讲解。总览 目标:一篇文章理清 iOS 三个紧密相关但层次不同的事物:操作系统(iOS / Darwin):谁在管理 “进程、线程、虚拟内存页、文件描述…

2025年12月天津金蝶软件代理商最新推荐:天津鹏越软件,金蝶云星空、金蝶云星晨、金蝶云星翰、助力企业高效落地ERP系统与全场景管理升级

随着数字经济加速渗透,企业对专业化、定制化管理软件的需求持续攀升,尤其是在生产流程优化、财务精益化管控、多组织协同等核心场景中,优质的数字化解决方案已成为企业提升竞争力的关键。2025 年,天津地区企业数字…

102302114_比山布努尔兰_作业4

作业1 熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。 使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。 作业代码点击查看代…

2025年12月济南艺考画室最新推荐:济南大道画室,济南艺考画室、济南画室哪家好、济南画室推荐、山东美术艺考培训、山东画室个性化教学新标杆

随着美术艺考竞争日益激烈、教学标准化要求提升及学生个性化发展需求增加,优质画室已从大城市集中逐步扩展至地方深耕,2025年艺考培训市场规模预计持续增长。但市场扩张也带来画室教学水平、师资力量、升学成果参差不…

记一次磁盘占满的问题

说明 之前搭建的lobehub/lobe-chat网页AI问答突然不能用了。 于是重启docker遇到: yangx@ak:~$ docker run 23576ea8e726 docker: Error response from daemon: mkdir /var/lib/docker/overlay2/70e1042a088ffe1a6d26…

Redis提供的原子性命令

目录Redis提供的原子性命令主要类别的原子性命令:1. 字符串(String)原子操作2. 列表(List)原子操作3. 集合(Set)原子操作4. 哈希(Hash)原子操作5. 有序集合(Sorted Set)原子操作6. 位图(Bitmap)原子操作7…

多业态连锁环境管理系统:AI + 机器人闭环,坪效提升 16%

门店环境本是沉默的,却在无声处酿成大祸:高峰无人知地面湿滑,夜间无人见灯闪,雨天无人管玻璃污——2025年,环境设施异常导致的综合损失平均占运营成本19%,保洁+维修双线超支,数据孤岛让决策如盲。全场景痛点全面…

2025年12月室内水上乐园厂家推荐:山东汇川,儿童水上乐园、大型水上乐园、主题水上乐园、室外水上乐园、恒温泳池、室 泳池、全场景适配新标杆

随着文旅产业升级、消费需求多元化及健康理念普及,水上游乐与泳池设备行业迎来快速发展期,2025 年市场规模预计持续扩大。但市场增长也带来厂商产品质量、场景适配性、服务专业性参差不齐的问题,企业及投资者在选购…

2025雅思培训班怎么选?这5家高性价比机构帮你高效提分

2025雅思培训班怎么选?这5家高性价比机构帮你高效提分一、雅思选课三大痛点解析:为什么你总在无效对比? 在雅思备考的漫漫征途中,选对培训班就如同找到了一把开启成功之门的钥匙。然而,面对市场上琳琅满目的雅思培…

实用指南:「腾讯云NoSQL」技术之向量数据库篇:自研分布式向量数据库,实现毫秒级时序一致备份的挑战和实践

实用指南:「腾讯云NoSQL」技术之向量数据库篇:自研分布式向量数据库,实现毫秒级时序一致备份的挑战和实践2025-12-09 20:11 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap:…

Semaphore、CountDownLatch、ReentrantLock使用场景简单说说

目录Semaphore、CountDownLatch、ReentrantLock使用场景简单说说1. Semaphore(信号量)2. CountDownLatch(倒计时门闩)3. ReentrantLock(可重入锁)对比总结简单记忆三个并发工具的简单示例1. Semaphore 示例 - 停…

LATTICE HW-USBN-2B 高速下载器凭什么是销冠

LATTICE HW-USBN-2B 高速下载器凭什么是销冠 1). 支持windows7,Windows10 操作系统,两个操作系统非常稳定不断线。2). 支持JTAG 模式,速度快,最高30Mb/s,调试serdes core,不会像hw-usbn-2a出现错误。如这种错误…

py-lambda-map-list随笔

py-lambda-map-list随笔 匿名函数lambda lambda 表达式用于创建 小型、匿名 的单行函数。 语法:lambda arguments: expression很方便的map()用于及其方便地映射 把相同的操作(如lambda表达式)映射到后者(如列表上)…

2025年12月水上乐园设备厂家最新推荐:昊至泉充气水上乐园设备、室内水上乐园设备、户外水上乐园设备、大型水上乐园设备、漂流河水上乐园设备、打造安全创新个性化水上娱乐新标准

随着全民休闲娱乐需求增长及文旅产业升级,水上乐园作为夏季热门旅游目的地,其设备安全性、创新性及个性化设计已成为投资运营者的核心考量。2025年,市场对水上乐园设备的要求已从基础功能转向安全高效、主题鲜明、适…

杂题选记

记录一些我觉得比较有意思的题目。难度差异可能会很大。 书信 给一个字符串 \(S\),对于 \(S\) 中的每一类字符,可以选择一个区间 \([l,r]\) 保留,保留的字母间相对顺序不变。 每一个位置有权值 \(w_i\)。 求将 \(S\…

2025年12月铝材厂家推荐榜:廊坊国美铝业,工业铝材、门窗铝材、3C铝材、通用铝材、多领域铝材定制与绿色生产标杆

随着 2025 年国内基建项目集中开工、新能源产业加速扩张及绿色建筑标准全面落地,铝材作为工业制造与建筑领域的核心基础材料,市场需求持续攀升。但当前市场上厂商技术水平、产品适配能力及环保合规性差异显著,企业在…

Qt 文本转语言(QTextToSpeech类)详解 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

AWS发布网络扫描指南:构建更安全云环境的守则

亚马逊云科技(AWS)正式发布针对客户工作负载的网络扫描行为指导原则。该指南旨在帮助合规扫描工具获取更准确数据,减少滥用报告,并提升整体互联网安全,涵盖了扫描行为的可观测性、可识别性、协作性与保密性四大核…