Condition源码解读(二)

本章我们继续将Condition的最后一个方法signal方法,如果前面没有看过的可以点击LockSupport与Condition解析来看看Condition解读的前半部分。

signal方法:

        public final void signal() {if (!AbstractQueuedLongSynchronizer.this.isHeldExclusively()) {throw new IllegalMonitorStateException();} else {Node var1 = this.firstWaiter;if (var1 != null) {this.doSignal(var1);}}}

signal方法的主要作用就是将线程从Condition队列中唤醒,前面已经讲述过在Condtion的子类ConditionObject内部通过链表来维护整个Condtion队列,并且含有两个属性firstWaiter和lastWaiter分别表示队列头和队列尾部,分析方法首先进行检查当前线程是否持有独占锁。目的是保证持有锁的线程才能调用signal方法来唤醒线程,通过判断之后开始从Condition队列中取出队首线程,随后开始调用doSignal方法来唤醒线程

        private void doSignal(Node var1) {do {if ((this.firstWaiter = var1.nextWaiter) == null) {this.lastWaiter = null;}var1.nextWaiter = null;} while(!AbstractQueuedLongSynchronizer.this.transferForSignal(var1) && (var1 = this.firstWaiter) != null);}

在dosignal中首先将后面的node设置为链表头部,如果后续没有node则将尾链表置为null。

同时调用transferForSignal(first)尝试将节点转移到同步队列,如果转移失败(返回false)且队列还有节点(firstWaiter != null),继续处理下一个节点。

下面我们来看看transferForSignal方法是如何进行转移的。

 final boolean transferForSignal(Node var1) {if (!compareAndSetWaitStatus(var1, -2, 0)) {return false;} else {Node var2 = this.enq(var1);int var3 = var2.waitStatus;if (var3 > 0 || !compareAndSetWaitStatus(var2, var3, -1)) {LockSupport.unpark(var1.thread);}return true;}}

首先进行状态位的CAS设置,如果无法设置表明状态已经改变了直接返回false,表示无法入队。

之后进行入队enq操作(内部是一个循环不断的CAS操作保证能入队)入队完毕之后则查看当前节点状态如果还是阻塞状态则直接调用unpark来唤醒当前线程。

1. 先判断当前线程是否持有当前锁没有则抛出异常

2. 取出Condition队列中的一个首节点尝试入队和唤醒操作

3.失败则再次循环从队伍中取出节点

4.在尝试入队的方法总首先会判断状态值是否符合不符合则直接返回false,符合则会通过CAS循环入队操作,最后判断状态是否为阻塞,为阻塞则直接调用unpark方法进行唤醒操作。

至此Condtion的两个方法已经介绍完毕。

总结:

await方法:

signal方法:

设计精髓

  1. 双队列分离:条件队列(等待条件)与同步队列(竞争锁)分离

  2. 状态驱动waitStatus 精确控制节点生命周期

  3. 无锁算法:CAS 操作保证线程安全

  4. 协作式唤醒:前驱节点负责唤醒后继

  5. 资源继承:await() 返回时自动恢复原始锁状态

典型应用场景

  1. 生产者-消费者:不同条件控制队列空/满

  2. 线程池任务调度:工作线程等待任务到达

  3. 资源池管理:连接可用性通知

  4. 屏障实现:所有线程到达后同时释放

  5. 状态机转换:特定状态变更触发操作

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

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

相关文章

股票收益率的计算

首先,需要从 Tushare.pro 注册一个账号并调用其API获取股票日线数据(具体操作请查看官网)。 以通过调用tushare获取股票000001(平安银行)的股票数据为例,这里不设置日期,那么默认获取Tushare提供的所有历史数据。也可…

《算法笔记》13.2小节——专题扩展->树状数组(BIT) 问题 D: 数列-训练套题T10T3

数列(sequence.pas/c/cpp) - 问题描述 一个简单的数列问题&#xff1a;给定一个长度为n的数列&#xff0c;求这样的三个元素ai, aj, ak的个数&#xff0c;满足ai < aj > ak&#xff0c;且i < j < k。 - 输入数据 第一行是一个整数n(n < 50000)。 第二行n个整…

C# Windows Forms应用程序-001

目录 项目概述 主要组件及功能 类定义 控件声明 构造函数 Dispose 方法 InitializeComponents 方法 控件配置详解 Button 控件 (button1) TextBox 控件 (textBox1) GroupBox 控件 (groupBox1) Label 控件 (label1 至 label5) OpenFileDialog 控件 (openFileDialog1…

2025.5.28总结

今日工作&#xff1a;最近进入了项目的关键节点&#xff0c;要求每人每天提两单&#xff0c;今天周三&#xff0c;下班前只提了一个单。下午开了一场需求服务验收会&#xff0c;我演示了自己验收的那个需求&#xff0c;然后讲的不是很好。当初再构造数据时请教了一个人&#xf…

Transformer核心技术解析LCPO方法:精准控制推理长度的新突破

原创文章1FFN前馈网络与激活函数技术解析&#xff1a;Transformer模型中的关键模块2Transformer掩码技术全解析&#xff1a;分类、原理与应用场景3【大模型技术】Attention注意力机制详解一4Transformer模型中位置编码&#xff08;Positional Embedding&#xff09;技术全解析(…

在 WSL 中安装 JetBrains Toolbox:完整指南

JetBrains Toolbox 是一个非常实用的工具&#xff0c;它可以帮助开发者轻松管理 JetBrains 的各种开发工具&#xff0c;如 IntelliJ IDEA、PyCharm、WebStorm 等。通过它&#xff0c;你可以快速安装、更新和管理这些工具&#xff0c;极大地提高了开发效率。而在 WSL 环境中安装…

ZooKeeper 命令操作

文章目录 Zookeeper 数据模型Zookeeper 服务端常用命令Zookeeper 客户端常用命令 Zookeeper 数据模型 ZooKeeper 是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似&#xff0c;拥有一个层次化结构。这里面的每一个节点都被称为&#xff1a; ZNode&#xff0c;每个节…

Turf.js:前端地理空间分析的瑞士军刀

在Web开发中,地理空间数据处理已成为许多应用的核心需求。从地图可视化到位置服务,再到复杂的数据分析,前端开发者需要强大的工具来处理这些任务。Turf.js 作为一款轻量级、模块化的地理空间分析库,凭借其丰富的功能和易用性,成为前端开发者的得力助手。本文将深入探讨 Tu…

大模型微调

使用 Ollama 微调大语言模型&#xff08;如 LLaMA、Mistral、Gemma 等&#xff09;主要是围绕 LoRA&#xff08;Low-Rank Adaptation&#xff09;或者 QLoRA 等轻量级微调技术进行的。Ollama 本身是一个部署和运行本地大语言模型的平台&#xff0c;但其微调能力有限&#xff0c…

《自动驾驶轨迹规划实战:Lattice Planner实现避障路径生成(附可运行Python代码)》—— 零基础实现基于离散优化的避障路径规划

《自动驾驶轨迹规划实战&#xff1a;Lattice Planner实现避障路径生成&#xff08;附可运行Python代码&#xff09;》 —— 零基础实现基于离散优化的避障路径规划 一、为什么Lattice Planner成为自动驾驶的核心算法&#xff1f; 在自动驾驶的路径规划领域&#xff0c;Lattice…

切换到旧提交,同时保证当前修改不丢失

在 Git 中&#xff0c;可以通过以下几种方式切换到之前的提交&#xff0c;同时保留当前的提交&#xff08;即不丢失工作进度&#xff09;&#xff1a; 1. 使用 git checkout 创建临时分离头指针&#xff08;推荐用于查看&#xff09; git checkout <commit-hash>这会让…

zookeeper 操作总结

zookeeper 中的节点类型 节点类型命令选项说明‌持久节点‌无选项&#xff08;默认&#xff09;永久存在&#xff0c;除非手动删除。‌临时节点‌-e与客户端会话绑定&#xff0c;会话结束自动删除&#xff08;‌不能有子节点‌&#xff09;。‌顺序节点‌-s节点名自动追加递增…

nova14 ultra,是如何防住80°C热水和10000KPa水压冲击的?

暴雨突袭&#xff0c;手忙脚乱护住背包&#xff0c;却担心手机被雨水浸湿&#xff1b;泳池里想记录美好时刻&#xff0c;却担心手机掉入水中 &#xff1b;厨房里充满了高温水汽&#xff0c;近距离拍摄美食瞬间&#xff0c;手机屏幕花屏&#xff0c;让人失去了对美食的兴趣…… …

flutter加载dll 报错问题

解决flutter加载dll 报错问题 LoadLibrary 报错 126 or 193 明确一点&#xff1a;flutter构建exe 时默认是MSVC的。 1. 先检查dll 的位数是否满足 file ***.dll output: PE32 executable (DLL) (console) x86-64, for MS Windows, 19 sections 这种是64位的机器。 满足的话可…

Mac 版不能连接华为 GaussDB 吗?我看 Windows 版可以连接?

&#x1f9d1;‍&#x1f4bb; GaussDB 用户 Mac 版不能连接华为 GaussDB 吗&#xff1f;我看Windows 版可以连接。 &#x1f9d1;‍&#x1f527; 官方技术中心 由于 GaussDB 数据库本身未支持 macOS 系统&#xff0c;所以在 macOS 上的 Navicat 中也未支持该数据库。 &…

【MySQL成神之路】MySQL索引相关介绍

1 相关理论介绍 一、索引基础概念 二、索引类型 1. 按数据结构分类 2. 按功能分类 三、索引数据结构原理 B树索引特点&#xff1a; 哈希索引特点&#xff1a; 四、索引使用原则 1. 创建索引原则 2. 避免索引失效情况 五、索引优化策略 六、索引维护与管理 七、特殊…

五、web安全--XSS漏洞(1)--XSS漏洞利用全过程

本文章仅供学习交流&#xff0c;如作他用所承受的法律责任一概与作者无关1、XSS漏洞利用全过程 1.1 寻找注入点&#xff1a;攻击者首先需要找到目标网站中可能存在XSS漏洞的注入点。这些注入点通常出现在用户输入能够直接输出到页面&#xff0c;且没有经过适当过滤或编码的地方…

使用 Shell 脚本实现 Spring Boot 项目自动化部署到 Docker(Ubuntu 服务器)

使用 Shell 脚本实现 Spring Boot 项目自动化部署到 Docker&#xff08;Ubuntu 服务器&#xff09; 在日常项目开发中&#xff0c;我们经常会将 Spring Boot 项目打包并部署到服务器上的 Docker 环境中。为了提升效率、减少重复操作&#xff0c;我们可以通过 Shell 脚本实现自动…

高考加油(Python+HTML)

前言 询问DeepSeek根据自己所学到的知识来生成多个可执行的代码&#xff0c;为高考学子加油。最开始生成的都会有点小问题&#xff0c;还是需要自己调试一遍&#xff0c;下面就是完整的代码&#xff0c;当然了最后几天也不会有多少人看&#xff0c;都在专心的备考。 Python励…

HTTP协议接口三种测试方法之-JMeter(保姆教程)

在当今 API 驱动的开发世界中&#xff0c;高效、可靠的 HTTP 接口测试是保障应用质量的关键。作为开源性能测试工具中的王者&#xff0c;Apache JMeter 不仅擅长压力测试&#xff0c;更是进行功能性和回归测试的利器。本文将手把手教你如何用 JMeter 构建强大的 HTTP 测试计划&…