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

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. 状态机转换:特定状态变更触发操作

相关文章:

  • 基于物理约束的稀疏IMU运动捕捉系统
  • Spring AI 集成多个大语言模型
  • canal高可用配置
  • Linux中的Shell脚本基础
  • 2025年5月通信科技领域周报(5.19-5.25):太赫兹通信规模商用启动 空天地一体化网络加速落地
  • 亚古数据:查询BVI(英属维尔京群岛)公司可以获取到什么信息和文件?
  • Cesium实现标注动画
  • get_rga_thread线程和low_camera_venc_thread线程获取低分辨率VENC码流数据
  • WES(二)——数据预处理
  • 美颜SDK功能模块化设计实战:滤镜、贴纸与人脸识别的协同实现
  • YOLOv8 区域计数系统:基于计算机视觉的智能物体计数方案
  • 各类效果名称收集
  • Nacos 服务注册发现案例:nacos-spring-cloud-example 详解
  • Django实现文件上传
  • 数据结构 -- 树相关面试题
  • 网络出版服务许可证年检
  • go实例化结构体的方式
  • 无法发布到PowerBI?试试拆分它
  • 天数计算卡 报错和解决记录
  • 玻纤效应的时序偏差
  • 厦门做商城网站/客源软件哪个最好
  • 临西网站建设/百度app下载并安装
  • 体育彩票网站开发该做哪些步骤/一个完整的营销策划案范文
  • 贵州移动端网站建设/个人建网站步骤
  • 在哪个网站有兼职做/seo排名app
  • 自己做网站地图/中山百度推广公司