Java Lock LockSupport 总结

前言


 相关系列

  • 《Java & Lock & 目录》(持续更新)
  • 《Java & Lock & LockSupport & 源码》(学习过程/多有漏误/仅作参考/不再更新)
  • 《Java & Lock & LockSupport & 总结》(学习总结/最新最准/持续更新)
  • 《Java & Lock & LockSupport & 问题》(学习解答/持续更新)
     
     

概述


 简介

    LockSupport @ 锁支持类是位于JUC包下基于“许可”对线程等待/唤醒进行控制的线程管理工具类。锁支持类对线程赋予了许可概念,并通过以1为单位对许可进行分配/消费来控制线程的状态在等待/运行之间相互切换。新创建启动的线程许可数量默认为0,并最多允许储存/透支一个许可,故而线程的许可数量只能在[-1, 0, 1]三个值之间波动,因此在线程许可数量达到高/低上限的情况下锁支持类对线程许可的分配/消费是没有意义的。

    新创建启动的线程会因为许可平衡(0)而处于运行状态,此时如果锁支持类消费了该线程的许可,则其将因为许可负债(-1)而进入有限/无限等待状态,在这种情况下正常只有分配、中断及超时才能令其许可平衡(0)而恢复运行。但如果锁支持类对许可平衡(0)的线程进行了许可分配,则线程将因为许可结余(1)而避免在下次许可消耗中因为许可负债(-1)而进入等待状态,即其会拥有一次等待的豁免权。

    因锁支持类而等待的线程在被中断唤醒后会在不抛出中断异常的同时保留中断状态。与因为Thread.sleep(long millis)方法而进入等待状态线程不同,因为许可负债(-1)而进入等待状态的线程在被中断唤醒后不会抛出中断异常,并会同时保留中断状态。因此对于锁支持类的调用者而言其可能需要基于需求人为地判断线程是否中断,并选择是否清除中断状态及抛出中断异常。

    因锁支持类而等待的线程可能发生虚假唤醒。所谓虚假唤醒是指等待线程在分配、中断及超时都未发生的情况下无理由唤醒的情况,因此对于线程许可的消费往往需要在循环中进行。循环的退出条件通常即为线程的唤醒条件,例如等待线程只有在某操作成功的情况下才会被唤醒,则被唤醒后的线程就需要去判断某操作是否已经执行成功,成功则退出循环执行下游代码;否则便再次进入等待状态,以此来避免因为虚假唤醒而导致的程序逻辑紊乱…相关调用示例如下:

while (!canProceed()) { ... LockSupport.park(this); 
}

 
 

方法


  • public static void park() —— 停泊 —— 消耗指当前线程的一个许可,消耗后如果当前线程许可负债(-1)则无限等待至因为信号、中断及虚假而唤醒为止;否则直接返回。

  • public static void park(Object blocker) —— 停泊 —— 消耗指当前线程的一个许可,消耗后如果当前线程许可负债(-1)则无限等待至因为信号、中断及虚假而唤醒为止;否则直接返回。

  • public static void parkNanos(long nanos) —— 停泊纳秒 —— 消耗指当前线程的一个许可,消耗后如果当前线程许可负债(-1)则在指定等待时间内有限等待至因为信号、中断、超时及虚假而唤醒为止;否则直接返回。

  • public static void parkNanos(Object blocker, long nanos) —— 停泊纳秒 —— 消耗指当前线程的一个许可,消耗后如果当前线程许可负债(-1)则在指定等待时间内有限等待至因为信号、中断、超时及虚假而唤醒为止;否则直接返回。

  • public static void parkUntil(long deadline) —— 停泊直至 —— 消耗指当前线程的一个许可,消耗后如果当前线程许可负债(-1)则在指定等待时间内有限等待至因为信号、中断、超时及虚假而唤醒为止;否则直接返回。该方法与parkNanos(…)方法的区别在于其是要等待至什么时间,而非要等待多少时间。

  • public static void parkUntil(Object blocker, long deadline) —— 停泊直至 —— 消耗指当前线程的一个许可,消耗后如果当前线程许可负债(-1)则在指定等待时间内有限等待至因为信号、中断、超时及虚假而唤醒为止;否则直接返回。该方法与parkNanos(…)方法的区别在于其是要等待至什么时间,而非要等待多少时间。

    可以发现,每个形式的停泊方法都会搭配一个功能完全相同但新增了阻塞者入参的同名方法。阻塞者的作用有些难以言明,但具体与探查/识别线程等待的状态有关。每个阻塞者形式的停泊方法都会在线程等待前将阻塞者存入线程,并于线程唤醒后清除,而在线程等待期间其它线程可以获取阻塞者对线程的等待进行状态、原因及时间等各项维度的探查,但探查的具体方式未知,这可能与阻塞者的自定义设计高度相关。

  • public static void unpark(Thread thread) —— 结束停泊 —— 为指定线程分配一个许可,如果指定线程原本许可负债(-1)而处于等待状态,则分配后将因为许可平衡(0)而恢复运行;如果指定线程原本许可平衡(0)而处于运行状态,则分配后将因为许可结余(1)而避免在下次许可消耗中因为许可负债(-1)而进入等待状态。
        注意!!!在线程尚未启动的情况,上述所有情况都不保证必然发生。

  • public static Object getBlocker(Thread t) —— 获取阻塞者 —— 获取指定线程的阻塞者快照,当指定线程正处于等待状态时正常返回;否则返回null。

  • static final int nextSecondarySeed() —— 下个次要种子 —— 基于当前线程的旧次要种子生成新的次要种子并保存/返回。当旧次要种子为0时说明其为初始值,通过随机分配的方式生成新次要种子。但如果新分配的次要种子依旧为0则需要在该情况下手动设置为1;如果旧次要种子不为0说明其已被更新过,通过位运算的方式生成新次要种子。

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

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

相关文章

php如何对海量数据进行基数统计

在PHP中,对海量数据进行基数统计通常可以使用布隆过滤器(Bloom Filter)或者Count-Min Sketch算法。以下是使用Count-Min Sketch算法的一个简单示例: class CountMinSketch {private $rows;private $columns;private $values;publ…

扫描开放端口的方法及代码实现telnet

背景:一个服务器不知道开放多少端口,也不知道有多少端口能用,因此扫描所有端口。 主要就是采用telnet来实现,挨个进行for训练 愿我们终有重逢之时,而你还记得我们曾经讨论的话题。 Q group 868373192 Q second group 277356808 `timeout` 命令的参数设置是正确的,但为…

高级java每日一道面试题-2024年10月22日-JVM篇-JVM堆栈概念,何时销毁对象?

如果有遗漏,评论区告诉我进行补充 面试官: JVM堆栈概念,何时销毁对象? 我回答: JVM堆栈概念 栈(Stack): 定义:栈是Java虚拟机为每个线程分配的内存区域,用于存储线程执行时的局部变量、操作数栈、动态链接和方法返…

串口调试工具

https://download.csdn.net/download/jinhuding/89933087?spm1001.2014.3001.5501

boost笔记:boost::Graph中找出所有环

1. 问题描述 本文描述了找出一个有向连通图中所有的环的解决方案 测试用到的有向连通图 2. 自写算法 通过深度优先遍历算法,发现回边时,即存在环的原理来找出环。对于用共享边的环,以下算法有些环找不出来,如上图中的2->8…

DriftingBlues: 1渗透测试

靶机:DriftingBlues: 1 DriftingBlues: 1 ~ VulnHubhttps://www.vulnhub.com/entry/driftingblues-1,625/ 攻击机:kail linux 2024 1,将两台虚拟机网络连接都改为NAT模式,并查看靶机的MAC地址 2,攻击机上做主机扫描发现靶机 靶机I…

【C++单调栈 记忆化搜索】1130. 叶值的最小代价生成树|1919

本文涉及的基础知识点 C单调栈 C记忆化搜索 C动态规划 LeetCode1130. 叶值的最小代价生成树 给你一个正整数数组 arr,考虑所有满足以下条件的二叉树: 每个节点都有 0 个或是 2 个子节点。 数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。 每…

【我的 PWN 学习手札】setcontext + ROP

堆上的setcontext利用系列还有: 【我的 PWN 学习手札】setcontext shellcode-CSDN博客 目录 前言 一、setcontext gadget 二、setcontext ROP (一)setcontext设置寄存器 (二)ROP链布置 三、图示 四、模板与…

【算法】Kruskal最小生成树算法

目录 一、最小生成树 二、Kruskal算法求最小生成树 三、代码 一、最小生成树 什么是最小生成树? 对于一个n个节点的带权图,从中选出n-1条边(保持每个节点的联通)构成一棵树(不能带环),使得…

信号完整性SI总结【小登培训】

信号完整性问题的根源通常在于阻抗不匹配、串扰、时序误差、电磁辐射和电源噪声。解决这些问题需要从PCB设计、布线、材料选择、匹配和屏蔽等多个方面综合考虑,并结合眼图分析等工具进行调试和优化。确保信号完整性对于高速电路设计尤为重要,影响系统的可…

【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python电话号码 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python电话号码 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

2022NOIP练习总结

种花 1.本题是一道前缀和优化加上枚举的问题。先考虑 C 因为 F 是 C 下边随便加一个点,所以只要求出 C 就求出了 F 。 注意到,并没有要求上下行一样,唯一的要求是 C 的两个横要隔一行,这就是问题的突破点,这题很明显…

【Spring Boot】元注解

元注解 1.元注解1.1 Target1.2 Retention1.3 Inherited1.4 Documented1.5 interface 2.自定义注解2.1 创建自定义注解类2.2 实现业务逻辑2.3 使用自定义注解 1.元注解 元注解就是定义注解的注解,是 Java 提供的用于定义注解的基本注解。 注解 说明 Retention是注解…

高速定向广播声光预警系统赋能高速安全管控

近年来,高速重大交通事故屡见不鲜,安全管控一直是高速运营的重中之重。如何利用现代化技术和信息化手段,创新、智能、高效的压降交通事故的发生概率,优化交通安全管控质量,是近年来交管部门的主要工作,也是…

Cmake Error:could not find any instance of Visual Studio.

出现以下错误 解决方案: 安装visual stuido 2017。 检查是否安装“使用C的桌面开发” 检查是否安装了扩展开发 点开“单个组件”是否安装了以下组件 编辑计算机环境变量,

kotlin定时器和主线程定时器

场景 最近要用kotlin写一个每隔一段时间切视频并截图 刷刷的就写出来了,很快啊 timerTask object : TimerTask() {override fun run() {captureWindow()if ((group 1) * 4 > urls.size) {showDialog()timerTask.cancel()timer.cancel()}groupupdatePlayers(…

美国大学生数学建模竞赛(MCM/ICM)介绍

美国大学生数学建模竞赛(MCM/ICM)是一项具有较高影响力的国际赛事。以下是一份美赛教程: 一、前期准备 组队 寻找合适的队友,最好具备不同的专业技能,如数学、计算机、工程等。团队成员应具备良好的沟通能力、合作精神和责任心。明确各自的分工,例如有人负责建模、有人负…

如何在macOS开发中给 PKG 签名和公证(productsign+notarytool)

在macOS中,给PKG文件进行签名是一个确保用户能够顺利无警告地安装软件的重要步骤。以下是给PKG签名的详细步骤: 一、准备阶段 获取开发者账号和证书: 首先,需要在苹果开发者网站(Apple Developer)注册一个…

EtherNet转Profinet主站网关以太网总线协议转换模块一文即可搞懂

稳联技术(WL-ABC2006)EtherNet/IP转Profinet网关是一种工业网络设备,它能够实现两种不同工业以太网协议之间的数据交换和通信。这种网关在工业自动化领域中非常重要,因为它允许不同品牌和协议的设备之间进行互联互通,从而提高了系统的灵活性和…

springboot配置websocket

springbootboot配置websocket import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component;import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.Map; import java…