多线程JUC 第2季 中断线程

一 中断线程

1.1 中断概念

1.在java中,没有提供一种立即停止一条线程。但却给了停止线程的协商机制-中断。

中断是一种协商机制。中断的过程完全需要程序员自己实现。也即,如果要中断一个线程,你需要手动调用该线程的interrupt()方法,该方法也仅仅是将线程对象中的中断标识设置成true;接着需要自己在方法中手动判断当前线程的标识位,如果为true,则中断线程。false标识未中断。

2.一个线程不应该由其他线程中断或者停止,而是有该线程自己自行停止,自己决定命运。

stop(),suspend,resume方法都已经废弃。

1.2 interrupt和isinterrupted和interrupted的作用

1.public void interrupt(): 实例方法,仅仅是设置线程中断状态为true,发起一个协商而不会立刻停止线程。

2.public static boolean interrupted;静态方法,判断当前线程是否中断并清除当前线程的中断状态。做两件事:

a)返回当前线程的中断状态,测试当前线程是否已经中断。

b)将当前线程的中断状态清零并重新设置为true,清除线程的中断状态。

3.public boolean isinterrupted():实例方法判断当前线程是不是中断,检测中断标志位。

1.3 interrupt的使用情况分析

当对一个线程,调用interrupt()时:

1.如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,仅此而已。

被设置中断标志的线程将继续正常运行,不受影响。

interrupt()并不能真正中断线程,需要被调用的线程自己进行配合才行。

2.如果线程处于被阻塞状态(sleep,wait,join等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞的状态,并抛出一个interruptedException异常。 

二 中断线程方式

2.1 方式1 通过volatile变量

package com.ljf.thread.interrupt;import java.util.concurrent.atomic.AtomicBoolean;/*** @ClassName: Zhongduan2* @Description: TODO* @Author: admin* @Date: 2024/03/02 17:43:01 * @Version: V1.0**/
public class Zhongduan2 {public static volatile boolean flag=false;static AtomicBoolean atomicBoolean = new AtomicBoolean(false);public static void main(String[] args) throws InterruptedException {Thread t1= new Thread(new Runnable() {@Overridepublic void run() {while(true){if(flag){//     if(atomicBoolean.get()){System.out.println("===================开始中断"+Thread.currentThread().getId());break;}else{System.out.println("循环中:"+Thread.currentThread().getId());}}}});t1.start();//主线程先休眠2秒Thread.sleep(5000);new Thread(new Runnable() {@Overridepublic void run() {flag=true;atomicBoolean.set(true);}}).start();}}

2.2  方式2 通过atomicboolean 原子类

public static volatile boolean flag=false;static AtomicBoolean atomicBoolean = new AtomicBoolean(false);public static void main(String[] args) throws InterruptedException {Thread t1= new Thread(new Runnable() {@Overridepublic void run() {while(true){// if(flag){if(atomicBoolean.get()){System.out.println("===================开始中断"+Thread.currentThread().getId());break;}else{System.out.println("循环中:"+Thread.currentThread().getId());}}}});t1.start();//主线程先休眠2秒Thread.sleep(5000);new Thread(new Runnable() {@Overridepublic void run() {flag=true;atomicBoolean.set(true);}}).start();}

2.3 方式3 通过interrupt+isinterrupted组合判断

package com.ljf.thread.interrupt;/*** @ClassName: Zhongduan* @Description: TODO* @Author: admin* @Date: 2024/03/02 17:34:59 * @Version: V1.0**/
public class Zhongduan {public static volatile boolean flag=false;public static void main(String[] args) throws InterruptedException {Thread t1= new Thread(new Runnable() {@Overridepublic void run() {while(true){if(Thread.currentThread().isInterrupted()){System.out.println("===================开始中断"+Thread.currentThread().getId());break;}else{System.out.println("循环中:"+Thread.currentThread().getId());}}}});t1.start();//主线程先休眠2秒Thread.sleep(5000);new Thread(new Runnable() {@Overridepublic void run() {t1.interrupt();}}).start();}
}

三 中断线程方式的情况分析

3.1 情况1

如果线程处于被阻塞状态(sleep,wait,join等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞的状态,并抛出一个interruptedException异常。

    public static void main(String[] args){//实例方法interrupt()仅仅是设置线程的中断状态位设置为true,不会停止线程Thread t1 = new Thread(() -> {for (int i = 1; i <=300; i++){System.out.println("-----: "+i);}System.out.println("t1线程调用interrupt()后的的中断标识02:"+Thread.currentThread().isInterrupted());}, "t1");t1.start();System.out.println("t1线程默认的中断标识:"+t1.isInterrupted());//false//暂停毫秒try { TimeUnit.MILLISECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }t1.interrupt();//trueSystem.out.println("t1线程调用interrupt()后的的中断标识01:"+t1.isInterrupted());//truetry { TimeUnit.MILLISECONDS.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println("t1线程调用interrupt()后的的中断标识03:"+t1.isInterrupted());//---false中断不活动的线程不会产生任何影响。}

线程t1执行300次后,已经不存在,2秒后查看t1线程的状态为false。

3.2 情况2

1.代码

public class InterruptDemo3
{public static void main(String[] args){Thread t1 = new Thread(() -> {while (true){if(Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName()+"\t " +"中断标志位:"+Thread.currentThread().isInterrupted()+" 程序停止");break;}try {Thread.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();//为什么要在异常处,再调用一次??e.printStackTrace();}System.out.println("-----hello InterruptDemo3");}}, "t1");t1.start();//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }new Thread(() -> t1.interrupt(),"t2").start();}
}

问题:报异常,程序没有停止

2.分析原因

* 1 中断标志位,默认false
* 2 t2 ----> t1发出了中断协商,t2调用t1.interrupt(),中断标志位true
* 3 中断标志位true,正常情况,程序停止,^_^
* 4 中断标志位true,执行sleep 后发生异常情况,InterruptedException,将会把中断状态将被清除,并且将收到InterruptedException 。中断标志位false
*    导致无限循环
*
* 5 在catch块中,需要再次给中断标志位设置为true,2次调用停止程序才OK

3.结论

3.3 情况3 关闭线程

https://blog.51cto.com/u_13316945/5832262

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);Future future = fixedThreadPool.submit(new Runnable() { @Override public void run() { 
new Runnable() {@Overridepublic void run() {/** 确保线程不断执行不断刷新界面*/while (true&&(!Thread.currentThread().isInterrupted())) {try {Log.i("tag","线程运行中"+Thread.currentThread().getId());// 每执行一次暂停40毫秒//当sleep方法抛出InterruptedException  中断状态也会被清掉Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();//如果抛出异常则再次设置中断请求Thread.currentThread().interrupt();}}}}
);
//触发条件设置中断
future.cancel(true);

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

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

相关文章

录制用户操作实现自动化任务

先上视频&#xff01;&#xff01; 流程自动化工具-录制操作绘制流程 这个想法之前就有了&#xff0c;趁着周末时间给它撸出来。 实现思路 从之前的文章自动化桌面未来展望中已经验证了录制绘制流程图的可行性。基于DOM录制页面操作轨迹的思路监听页面点击、输入事件即可&…

无人机镜头稳定的原理和相关算法

无人机的镜头稳定主要基于两个关键技术&#xff1a;镜头平衡技术和实时电子稳像。无人机镜头稳定的原理和相关算法主要是通过镜头平衡技术和实时电子稳像技术来保持摄像镜头的稳定性&#xff0c;从而拍摄出清晰、稳定的画面。无人机镜头稳定的原理主要是通过传感器和算法来实现…

Ocr之PaddleOcr模型训练

目录 一、系统环境 1 镜像拉取ppocr 进行部署 2 安装paddlepaddle 二、训练前的准备 1 下载源码 2 预模型下载 3 修改模型训练文件yml 4 编排训练集 5 执行脚本进行训练 6 需要修改文件夹名称 三、开始训练 1 执行训练命令 2 对第一次评估进行解释 3 引言 五、总…

NestJS使用模板引擎ejs

模板引擎​ 模板引擎是一种用于生成动态内容的工具&#xff0c;它通过将预定义的模板与特定数据结合&#xff0c;来生成最终的输出。​ 在NodeJS开发中&#xff0c;我们会使用模板引擎来渲染一些常用的页面&#xff0c;比如渲染代表404的Not Found 页面&#xff0c;502的Bad …

【【C语言简单小题学习-1】】

实现九九乘法表 // 输出乘法口诀表 int main() {int i 0;int j 0;for (i 1; i < 9; i){for (j 1; j < i;j)printf("%d*%d%d ", i , j, i*j);printf("\n"); }return 0; }猜数字的游戏设计 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdi…

源码视角,vue3为什么推荐用ref,而不是reactive

ref 和 reactive 是 Vue3 中实现响应式数据的核心 API。ref 用于包装基本数据类型&#xff0c;而 reactive 用于处理对象和数组。尽管 reactive 似乎更适合处理对象&#xff0c;但 Vue3 官方文档更推荐使用 ref。 我的想法&#xff0c;ref就是比reactive好用&#xff0c;官方也…

Java 中对包含关系的判断

本文将为您详细讲解 Java 中对包含关系的判断&#xff0c;包括数组、字符串等&#xff0c;并提供相应的代码例子。 1. 数组包含关系判断 在 Java 中&#xff0c;数组包含关系判断通常使用循环来实现。以下是几种常见的判断方法&#xff1a; 示例 1&#xff1a;使用 for…

Unity曲柄滑块四杆机构运动计算

一、运动效果 二、机构的介绍 曲柄长度&#xff1a;a&#xff0c;线段AB长度 连杆长度&#xff1a;b&#xff0c;线段BC长度 偏心距离&#xff1a;e&#xff0c;滑块轨迹与曲柄中心点A的垂直距离 三、已知点A点B和e的值&#xff0c;计算C点的位置 1、计算s的值 var h math.…

通过多进程并发方式(fork)实现服务器(注意要回收子进程)

以下内容为视频学习记录。 1、父进程accept后返回的文件描述符为cfd以及用于创建连接的lfd; 调用fork()创建子进程后&#xff0c;子进程继承cfd,lfd&#xff0c;通过该cfd与连接过来的客户端通信,lfd对子进程来说没用&#xff0c;可以直接close(lfd); 对于父进程来说&#x…

Vue中的计算属性和方法有什么区别?

Vue.js是一款流行的JavaScript前端框架&#xff0c;提供了丰富的功能和便捷的开发方式。在Vue中&#xff0c;计算属性和方法是常用的两种方式来处理数据和逻辑。但它们之间存在一些区别&#xff0c;本文将详细介绍Vue中计算属性和方法的区别&#xff0c;并通过示例代码加深理解…

183896-00-6,Biotin-C3-PEG3-C3-NH2,可以选择性降解靶蛋白

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;183896-00-6&#xff0c;Biotin-C3-PEG3-C3-NH2&#xff0c;Biotin-C3-PEG3-C3-amine&#xff0c;生物素-C3-PEG3-C3-胺 一、基本信息 【产品简介】&#xff1a;Biotin-PEG3-C3-NH2是一种PROTAC linker&#xff0c;…

Python推导式大全与实战:精通列表、字典、集合和生成器推导式【第115篇—python:推导式】

Python推导式大全与实战&#xff1a;精通列表、字典、集合和生成器推导式 Python语言以其简洁、优雅的语法而闻名&#xff0c;其中推导式是其独特之处之一。推导式是一种在一行代码中构建数据结构的强大方式&#xff0c;它涵盖了列表、字典、集合和生成器。本篇博客将全面介绍…

YOLOv8实例分割实战:ONNX模型转换及TensorRT部署

课程链接&#xff1a;https://edu.csdn.net/course/detail/39320 PyTorch版的YOLOv8支持高性能的实时实例分割。 TensorRT是针对英伟达GPU的加速工具。 ONNX &#xff08;Open Neural Network Exchange&#xff09; 作为一个开放的网络模型中间表示&#xff08;IR&#xff0…

spring boot 修复 Spring Framework URL解析不当漏洞(CVE-2024-22243)

漏洞描述 当应用程序使用UriComponentsBuilder来解析外部提供的URL&#xff08;如通过查询参数&#xff09;并对解析的URL的主机执行验证检查时可能容易受到Open重定向攻击和SSRF攻击&#xff0c;导致网络钓鱼和内部网络探测等。 受影响产品或系统 6.1.0 < Spring Framew…

Vue项目的快速搭建

Vue项目的快速搭建 一、下载并安装node.js二、安装Vue脚手架三、创建vue项目四、项目启动五、VS Code下载安装 一、下载并安装node.js 首先确保已经安装了Node.js。如果没有安装&#xff0c;可以去官网&#xff08;https://nodejs.org/&#xff09;下载并安装最新版本的Node.j…

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍TM1638键盘数码管模块概述TM1638键盘数码管…

蓝桥杯倒计时 41天 - KMP 算法

KMP算法 KMP算法是一种字符串匹配算法&#xff0c;用于匹配模式串P在文本串S中出现的所有位置。 例如S“ababac&#xff0c;P“aba”&#xff0c;那么出现的所有位置是13。 在初学KMP时&#xff0c;我们只需要记住和学会使用模板即可&#xff0c;对其原理只需简单理解&#xff…

Django 官网项目 四

内容&#xff1a; 利用HTTP的post方法&#xff0c;更改数据并显示。 创建detail.html文件&#xff0c;来创建POST内容 修改应用的视图文件views.py&#xff0c;vote方法 修改应用的视图文件views.py&#xff0c;results方法。 创建results.html文件。 结果&#xff1a;单…

.NET开源功能强大的串口调试工具

前言 今天大姚给大家分享一款.NET开源的、功能强大的串口调试工具&#xff1a;LLCOM。 工具介绍 LLCOM是一个.NET开源的、功能强大的串口调试工具。支持Lua自动化处理、串口调试、串口监听、串口曲线、TCP测试、MQTT测试、编码转换、乱码恢复等功能。 功能列表 收发日志清晰…

flynn发布服务小结

背景 flynn是一个基于容器的paas平台&#xff0c;可以快速的发布运行新的应用&#xff0c;用户只需要提交代码到git上&#xff0c;flynn就会基于提交的代码进行发布和部署&#xff0c;本文就简单看下flynn发布部署的流程 flynn发布服务 1.首先flynn会基于用户的web代码构建一…