【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…...
量子计算中Loschmidt回声相位测量的创新方法
1. 量子计算中的Loschmidt回声相位测量方法概述Loschmidt回声是量子动力学中一个重要的概念,它描述了量子系统在时间反演演化后与初始状态的相似程度。在量子计算领域,精确测量Loschmidt回声的相位信息对于理解量子系统的非平衡态行为、计算能量本征值以…...
对称与负电源测试:动态直流电子负载的设计、原理与应用
1. 项目概述:对称与负电源的静态与动态直流负载在电子实验室里,测试一个电源的性能,尤其是它的动态响应能力,是件既基础又关键的事。我们常说的“直流电子负载”就是这个领域的核心工具。我之前设计并分享过一个用于正电源测试的静…...
AI学习 - 大模型基础入门
AI学习 - 大模型基础入门 从零开始:Ollama 安装 → 本地模型运行 → Python 代码接入 → 理解核心概念 摘要 本文记录了在 Windows 上使用 Ollama 部署本地大模型、并通过 Python 代码接入调用的完整过程。内容涵盖:Ollama 安装与模型拉取、大模型基础概…...
Claude SWOT分析(内部风控文档流出版):3类高危使用场景+2个监管红线预警
更多请点击: https://intelliparadigm.com 第一章:Claude SWOT分析(内部风控文档流出版):3类高危使用场景2个监管红线预警 高危使用场景识别 在企业级AI应用中,Claude模型若未经严格风控适配,…...
为什么你的DeepSeek微调loss震荡不止?(Meta/DeepSeek联合团队未公开的梯度裁剪+LoRA初始化双校准协议)
更多请点击: https://codechina.net 第一章:DeepSeek微调loss震荡的根本归因剖析 DeepSeek系列模型在微调过程中频繁出现loss剧烈震荡现象,其本质并非单一因素所致,而是数据、优化器、梯度动态与模型结构四者耦合失稳的系统性表现…...
别再只用鼠标了!用Leap Motion手势控制Unity游戏,保姆级配置避坑指南(2024版)
2024年Unity手势交互开发实战:Leap Motion从配置到游戏逻辑全解析在游戏开发领域,交互方式的创新往往能带来全新的体验。想象一下,玩家不再需要键盘鼠标,仅凭自然的手部动作就能操控游戏角色——这正是Leap Motion手势识别技术为U…...
万星easy-vibe:描述需求即发布 零基础无需学语法
开源Easy-Vibe是一套开源AI编程学习方案,把学习顺序从先学语法再做项目翻转为直接做项目。文章拆解了项目驱动、提示词编写、AI编辑器和多Agent协作的完整流程,解释了为什么想法比语法更重要。 github上datawhalechina/easy-vibe:它在GitHub…...
【2026实测】怎么提高论文原创度?盘点8款主流降AI工具,附结构级优化指南
写文章最怕碰到什么,是辛辛苦苦自己码出来的字,却被标了极高的AI值。目前很多文本审核机制对内容的原创度要求极高,纯手写的初稿也可能因为句式太工整被判定为机器生成的。 为了帮几个快被这事折腾疯了的学弟学妹找条出路,我花了…...
3步快速上手Whisper-WebUI:轻松实现语音转字幕的完整指南
3步快速上手Whisper-WebUI:轻松实现语音转字幕的完整指南 【免费下载链接】Whisper-WebUI A Web UI for easy subtitle using whisper model. 项目地址: https://gitcode.com/gh_mirrors/wh/Whisper-WebUI 还在为视频制作繁琐的字幕而烦恼吗?Whis…...
Claude Agent SDK 从 0 到 1 快速上手教程
Claude Agent SDK 从 0 到 1 快速上手教程 什么是 Claude Agent SDK? Claude Agent SDK 是 Anthropic 官方推出的用于构建 AI 智能体的开发工具包。它基于 Claude Code 构建,让开发者能够以编程方式创建、扩展和定制由 Claude 驱动的应用程序。与简单的聊天机器人不同,基于…...
