【JUC2022】第三章 线程中断与 LockSupport
【JUC2022】第三章 线程中断与 LockSupport
文章目录
- 【JUC2022】第三章 线程中断与 LockSupport
- 一、线程中断
- 1.什么是中断机制
- 2.中断 API
- 3.代码实现
- 4.Thread.sleep()
- 二、LockSupport
- 1.什么是 LockSupport
- 2.代码实现
- 3.总结
一、线程中断
1.什么是中断机制
首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己停止,自己来决定自己的命运。所以,Thread.stop,Thread.suspend,Thread.resume 都已经被废弃了
其次,在 Java 中没有办法立即停止一条线程,然而停止线程却尤为重要,如取消一个耗时操作。因此,Java 提供了一种用于停止线程的协商机制——中断,也即中断标识协商机制
中断只是一种协商机制,Java 没有给中断增加任何语法,中断的过程完全需要程序员自己实现
若要中断一个线程,需要手动调用该线程的 interrupt 方法,该方法也仅仅是将线程对象的中断标识设成 true。接着你需要自己写代码不断地检测当前线程的标识位,如果为 true,表示别的线程请求这条线程中断,此时究竟该做什么需要自己写代码实现
每个线程对象中都有一个中断标识位,用于表示线程是否被中断。该标识位为 true 表示中断,为 false 表示未中断。通过调用线程对象的 interrupt 方法将该线程的标识位设置为 true,可以在别的线程中调用,也可以在自己的线程中调用
2.中断 API
public void interrupt()
设置线程的状态为 true,发起一个协商而不会立刻停止线程
如果该线程已经执行了 wait()、join()、sleep()方法,此时其他线程调用该线程的 interrupt() 方法,那么该线程将立即退出阻塞状态,并抛出 InterruptedException
public static boolean interrupted()
返回当前线程的中断状态,并将当前线程的中断标识位重新设置为 false
这里可能会有一点抽象,读者朋友可能会疑惑为什么要重新设置中断标识位为 false。我觉得这只是一个表述问题,因为这个方法的主要功能就是将线程的中断标识位设置为 false,而不是返回中断状态。我们会发现,如果没有这个方法,我们就没有其他方法去重置线程的中断标识位了
public boolean isInterrupted()
返回当前线程的中断标识位
3.代码实现
package com.sisyphus.Interrupt;import java.util.concurrent.TimeUnit;public class InterruptDemo {public static void main(String[] args) {Thread t1 = new Thread(()->{while(true){if (Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName() + "线程被中断");break;}System.out.println("线程运行中...");}},"t1");t1.start();//暂停try{TimeUnit.MILLISECONDS.sleep(20);}catch (InterruptedException e){e.printStackTrace();}new Thread(()->{t1.interrupt();},"t2").start();}
}
4.Thread.sleep()
为什么 Thread.sleep() 要抛中断异常
为了让线程具备感知中断能力。不能让线程无感知地一直睡眠,总会有需要“叫醒”它的突发情况
为什么 interrupt() “叫醒了”线程后要清除中断标志位
为了让线程能够继续执行本该执行的代码。线程中往往会使用 if(!Thread.currentThread().isInterrupted()) 来达到判断线程是否在睡眠中被中断的目的
如果需要实现睡眠中被中断,就不继续执行 if 代码块怎么办
需要我们在 catch 代码块中手动调用 interrupt()
try {Thread.sleep(100);
} catch (InterruptedException e) {//中断标志已经被清除了// 手动中断本线程,将本线程打上中断信号。Thread.currentThread().interrupt();
}
// Thread.currentThread().isInterrupted():是否被中断了(是否有中断标志)
if(!Thread.currentThread().isInterrupted()) {//如果没有被中断,则处理业务doSomething();
}
二、LockSupport
1.什么是 LockSupport
java.util.concurrent.locks.LockSupport
定义:用于创建锁和其它同步类的基本线程阻塞原语
LockSupport 有 park() 和 unpark() 两个重要方法,其作用分别是阻塞线程和解除阻塞线程
3 种让线程等待和唤醒的方法
- 使用 Object 中的 wait() 和 notify()
- 使用 JUC 包中的 Condition 和 await() 和 signal()
- 使用 LockSupport 中的 park() 和 unpark()
方法1和方法2存在的限制:
- 线程先要获得并持有锁
- 必须先执行等待,才能执行唤醒
Permit
LockSupport 使用了一种名为 Permit(许可) 的概念来做到阻塞和唤醒线程,每个线程都有一个 Permit,与 Semaphore 不同的是,Permit 的累加上限是 1
2.代码实现
package com.sisyphus.LockSupport;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;public class LockSupportDemo {public static void main(String[] args) {Thread t1 = new Thread(()->{System.out.println(Thread.currentThread().getName() + "\t -----come in");LockSupport.park();System.out.println(Thread.currentThread().getName() + "\t -----被唤醒");},"t1");t1.start();//暂停几秒钟线程try{TimeUnit.SECONDS.sleep(1);}catch (InterruptedException e){e.printStackTrace();}new Thread(()->{LockSupport.unpark(t1);System.out.println(Thread.currentThread().getName() + "\t -----发出通知");},"t2").start();}public static void lockUnlock() {Lock lock = new ReentrantLock();Condition condition = lock.newCondition();new Thread(()->{lock.lock();try{System.out.println(Thread.currentThread().getName() + "\t -----come in");condition.await();System.out.println(Thread.currentThread().getName() + "\t -----被唤醒");}catch (InterruptedException e){e.printStackTrace();}finally {lock.unlock();}},"t1").start();//暂停几秒钟线程try{TimeUnit.SECONDS.sleep(1);}catch (InterruptedException e){e.printStackTrace();}new Thread(()->{lock.lock();try{condition.signal();System.out.println(Thread.currentThread().getName() + "\t -----发出通知");}finally {lock.unlock();}},"t2").start();}public static void waitNotify() {Object objectLock = new Object();new Thread(()->{synchronized (objectLock){System.out.println(Thread.currentThread().getName() + "\t -----come in");try{objectLock.wait();}catch (InterruptedException e){e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "\t -----被唤醒");}},"t1").start();//暂停几秒钟线程try{TimeUnit.SECONDS.sleep(1);}catch (InterruptedException e){e.printStackTrace();}new Thread(()->{synchronized (objectLock){objectLock.notify();System.out.println(Thread.currentThread().getName() + "\t -----发出通知");}},"t2").start();}
}
3.总结
LockSupport 是一个线程阻塞工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞,阻塞之后也有对应的唤醒方法。归根结底,LockSupport 调用的是 Unsafe 中的 native 方法
当调用 park() 时
- 如果有凭证,则会直接消耗掉这个凭证,然后正常退出
- 如果没有凭证,就必须阻塞等待凭证可用
当调用 unpark() 时,会增加一个凭证,但最多只有一个,累加无效
因此,当连续调用 park() 时,线程必然阻塞,无论之前调用过多少次 unpark()
相关文章:
【JUC2022】第三章 线程中断与 LockSupport
【JUC2022】第三章 线程中断与 LockSupport 文章目录【JUC2022】第三章 线程中断与 LockSupport一、线程中断1.什么是中断机制2.中断 API3.代码实现4.Thread.sleep()二、LockSupport1.什么是 LockSupport2.代码实现3.总结一、线程中断 1.什么是中断机制 首先,一个…...
数据结构刷题(七):202快乐数、1两数之和、454四数相加II、15三数之和、18四树之和
1.快乐数题目链接思路:使用set,当set中出现相同元素时,返回false注意:while循环中语句顺序; 除数取余。解法:public boolean isHappy(int n){Set<Integer> res new HashSet<>();int[] arr ne…...
华为机试题:HJ80 整型数组合并(python)
文章目录知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。 1.1、int(input()) 与 map(int, input().spilt()) 的区别 1.2、input() 与 list(input()) 的区别、及其相互转换方法2、print() :打印输出…...
spring boot——自定义依赖实现自动配置
需求 要实现的功能是:实现一个可以支持miniooss两种方式,上传下载文件的自定义依赖。其中还包括一些创建桶、删除桶、删除文件等功能,但是最主要的是实现自动配置。 如果对spring理解很深的话,自动配置这些东西很容易理解&#…...
QMap 判断是否value是否已经存在,结合Sleep函数测试
网上查了资料,基本说的都是通过.value判断是否已经之前的key值,但是尝试.了一下发现有.key的函数,对比着来就感觉这个函数是用来判断是否已经存在value值,于是开始百度也几乎没有找到相关资料,只好自己看官方文档&…...
vue后台管理系统项目-table选择多行数据分页列表、一键全选重置功能
table选择多行数据 功能介绍: 1.列表分页功能; 2.一键全选,选中列表所有数据; 3.全选,选中当前页数据; 4.重置,清除选中状态; 5.列表搜索查询; 效果: 1.列表分…...
论文解读 | [CVPR2019] 基于自适应文本区域表示的任意形状场景文本检测
目录 1 研究背景及意义 2 总体设计 3 方法论 3.1 自适应文本区域表示 3.2 文本建议 3.3 建议改进 4 损失函数 5 实验及结果 1 研究背景及意义 现有的场景文本检测方法使用固定点数的多边形来 表示文本区域。例如,水平文本使用2个点(左上/右下)表示文本区域&…...
2月编程语言排行榜谁还没有看?
近日,TIOBE公布了2023年2月编程语言排行榜,本月各个语言表现如何?谁又摘得桂冠?一起来看看吧! TIOBE 2月Top15编程语言: 详细榜单查看TIOBE官网 https://www.tiobe.com/tiobe-index/ 关注IT行业的小伙伴们…...
nginx.conf配置方法详细介绍
从前面的内容学习中,我们知道Nginx的核心配置文件默认是放在/usr/local/nginx/conf/nginx.conf,这一节,我们就来学习下nginx.conf的内容和基本配置方法。读取Nginx自带的Nginx配置文件,我们将其中的注释部分【学习一个技术点就是在…...
【微信小程序】一文带你吃透开发中的常用组件
写在前面 小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构。 官方把小程序的组件分为了9大类,分别是: 1.视图容器 2.基础内容 3.表单组件 4.导航组件 5.媒体组件 6.地图组件 7.画布组件 …...
Nginx 部署 Vue 项目以及 Vue 项目刷新出现 404 的问题(完整步骤)(亲测有效)
Nginx 部署 Vue 项目以及 Vue 项目刷新出现 404 的问题(完整步骤)(亲测有效) 1.流程步骤(本教程下载的是1.20.2版本,放在D盘) 1-1. 首先去官方下载 nginx ,然后在当前目录下创建ht…...
leaflet 加载geojson数据,随机显示不同颜色的circleMarker
第086个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet项目中加载geojson数据,随机显示不同颜色的circleMarker. 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共89行)相关API专栏目标示例效果 配置方式…...
UL grant的分配(LCP)
欢迎关注同名微信公众号“modem协议笔记”。 UE有UL data时,会发送BSR的告知网络侧自己详细的请求,期望网络能够如期下发UL grant,正常情况下网络侧会给UE足够的UL grant去发送UL data,整个过程都会比较顺利。UE收到UL grant后&a…...
真我air笔记本电脑怎么重装Win10系统?
真我air笔记本电脑怎么重装Win10系统?最近真我air笔记本电脑挺多用户购买的,因为这款电脑性价比比较高,适合学生和一些办公人员来使用。但是系统预制了Win11系统,有用户想要将系统重装到Win10来使用。那么如何去进行系统的重装呢&…...
【闲聊杂谈】深入剖析SpringCloud Alibaba之Nacos源码
Nacos核心功能点 服务注册 Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中; 服…...
MySQL删除或清空表内数据的方法
MySQL删除或清空表内数据的方法 一、使用MySQL清空表数据命令:truncate SQL语法为: truncate table 表名注意: truncate该命令会直接将数据表内数据清空;truncate该命令删除数据后会重置Identity(标识列、自增字段…...
Android 权限(二): 动态权限讲解
1. 前言 继上一篇文章说到Android权限汇总, 请移步笔者的文章Android 权限(一):权限大全_broadview_java的博客-CSDN博客_android 仅使用中允许权限 先要理清楚权限分类和定义,本篇文章继续说一下动态权限的申请和框架层的实现流程, 以及如何实现赋予系统应用默认的…...
【C++】2.类和对象(上)
1.面向过程和面向对象 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。C是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。 2.类的引入…...
扬帆优配|3300点半日游!上证指数冲高回落;再迎重磅利好!
今天早盘,A股冲高回落,上证指数3300点得而复失,深证成指也于12000点无功而返。 盘面上,煤炭、钢铁、房地产、才智政务等板块涨幅居前,酿酒、酒店餐饮、日用化工、IT设备等板块跌幅居前。北上资金净流入7.77亿元。 房地…...
如何编写性能测试计划?一篇文章教你设计符合项目的性能测试计划
上篇文章,我们讲过性能测试计划,接下来我们就来讲讲如何设计符合项目的性能测试计划。到上篇为止,我们了解了性能测试计划中包含的内容,但是,这个颗粒度,我觉得作为一名测试经验不够丰富的性能工程师来说&a…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
