Java中线程中断的几种方式,你了解吗?

Java中线程,可以使用 interrupt() 方法来实现线程的中断,那么,线程中中断的方式有几种呢?接下来,我们将介绍3种不同的线程中断方式,跟随我们的脚步,一起去看看!

目录

  • 第一招:volatile 变量法
  • 第二招:AtomicBoolean 原子类型
  • 第三招:interrupt() 方法


种一棵树最好的时间是10年前,其次就是现在,加油!
                                                                                   --by蜡笔小柯南

第一招:volatile 变量法

使用 volatile 关键字,来保证数据的可见性,在多个线程之间,数据是可见的,代码如下:

public class InterruptTest {static volatile boolean flag = false;public static void main(String[] args) throws Exception {interruptedMethod1();}private static void interruptedMethod1() throws InterruptedException {Thread t1 = new Thread(() -> {while (true) {if (flag) {System.out.println(Thread.currentThread().getName() + " isInterrupted " + Thread.currentThread().isInterrupted());break;}System.out.println(Thread.currentThread().getName() + "...");}});t1.start();TimeUnit.MILLISECONDS.sleep(1);Thread t2 = new Thread(() -> {flag = true;});t2.start();}
}

声明 volatile boolean flag = false ,由于在 interruptedMethod1 方法中,分别启动了线程t1,线程t2,为了保证 flag 的值在两个线程间可见,以及保证数据的一致性,所以声明为 volatile.

代码解析:

  1. 创建 t1 线程,while(true) 循环中,根据 flag 的值进行判断,从而得出 t1 线程是否跳出此循环;如果 flag 的值为 true ,则跳出循环,否则,一直打印线程t1的名称
  2. 创建 t2 线程,t2 线程中,将flag的值修改为true,由于flag为多线程可见,所以 t1 线程中判断到了flag的值是true,则执行打印输出语句后,执行break,结束循环

第二招:AtomicBoolean 原子类型

使用原子布尔类型,在多线程环境下对布尔值的读取和设置操作是线程安全的,避免了线程间的冲突和数据不一致的问题‌

public class InterruptTest {static AtomicBoolean atomicBoolean = new AtomicBoolean(false);public static void main(String[] args) throws Exception {interruptedMethod2();}private static void interruptedMethod2() throws InterruptedException {Thread t1 = new Thread(() -> {while (true) {if (atomicBoolean.get()) {System.out.println(Thread.currentThread().getName() + " isInterrupted " + Thread.currentThread().isInterrupted());break;}System.out.println(Thread.currentThread().getName() + "...");}});t1.start();TimeUnit.MILLISECONDS.sleep(1);Thread t2 = new Thread(() -> {atomicBoolean.set(true);});t2.start();}
}

代码分析:

  1. 通过调用 get() 方法,获取所设置的 boolean 值,如果值为true,则跳出循环,否则,一直打印线程t1的名称
  2. 线程t2使用 set(true) 方法,修改为true,修改后被t1线程感知到,进入if判断,结束循环

第三招:interrupt() 方法

调用线程的 interrupt() 方法,注意:此方法只是给线程设置一个标识,表示线程可中断,而不是调用此方法后,线程被立即中断,具体是否中断,还需要代码中进行判断处理

isInterrupted() :获取线程的中断状态,如果线程设置了中断标识位,返回true,否则,返回false

public class InterruptTest {public static void main(String[] args) throws Exception {interruptedMethod3();}private static void interruptedMethod3() throws InterruptedException {Thread t1 = new Thread(() -> {while (true) {if (Thread.currentThread().isInterrupted()) {System.out.println(Thread.currentThread().getName() + " isInterrupted " + Thread.currentThread().isInterrupted());break;}System.out.println(Thread.currentThread().getName() + "...");}});t1.start();TimeUnit.MILLISECONDS.sleep(1);Thread t2 = new Thread(() -> {t1.interrupt();});t2.start();}
}

代码分析:

  1. t1 线程中,调用的当前线程的 Thread.currentThread().isInterrupted() 方法,来判断当前线程是否可中断,如果为true,则进入if分支,执行break后结束循环
  2. t2 线程中,调用 t1.interrupt() ,给 t1 线程设置中断标志位为true,t1线程通过 Thread.currentThread().isInterrupted() 获取到的值为true,进入if分支,执行break后结束循环

注意:

Thread中的静态方法,Thread.interrupted ,与 isInterrupted() 方法有区别,静态方法的作用是:返回当前线程的中断标志位,如果当前线程的中断标志为处于true,则返回true,并清除中断标志位的状态,重置为false,这个方法有两个作用,一是将中断标志位返回,二是清除中断标志位的状态


那么,如果连续调用2次这个 Thread.interrupted 方法,会有什么效果呢?

:如果线程没有被调用 interrupt 方法,调用两次返回的都是false;如果线程被调用了 interrupt 方法,则第一次调用返回true,第二次调用返回false



如果你有任何疑问或经验分享,可以在评论区留言哦~~

不管在任何时候,我希望你永远不要害怕挑战,不要畏惧失败。每一个错误都是向成功迈出的一步,每一个挑战都是成长的机会,因为每一次的努力,都会使我们离梦想更近一点。只要你行动起来,任何时候都不算晚。最后,把座右铭送给大家:种一棵树最好的时间是10年前,其次就是现在,加油!共勉 💪。
快来吧 👇👇👇

不论是Java的基础资料,还是那些看似枯燥实则精妙的八股文,这里都有你意想不到的解读方式,让复杂变简单,让枯燥变有趣~

在这里插入图片描述

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

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

相关文章

GESP5级语法知识(三):双向链表、循环链表

双链表的创建与输出&#xff1a; #include<cstdio> using namespace std; struct node {int data; //data记录这个结点对应元素的值node *next,*pre; //next指向后继 pre指向前驱 }*head,*tail,*p; int n,k; int main() {scanf("%d",&n);headnew no…

前端项目开发 常用的正则表达式

1.校验0-100的数字&#xff0c;仅支持两位小数点 numberCheck(rule, value, callback) {const checkReg /^(((\d|[1-9]\d)(\.\d{1,2})?)|100|100.0|100.00)$/if (checkReg.test(value)) {callback()} else {callback(new Error(0-100的数字&#xff0c;仅支持两位小数点))}},…

homework 2025.01.07 math 6

1选择部分 二填空部分

cursor vip

https://cursor.jeter.eu.org?pf7f4f3fab0af4119bece19ff4a4360c3 可以直接复制命令使用git bash执行即可 命令&#xff1a; bash <(curl -Lk https://gitee.com/kingparks/cursor-vip/releases/download/latest/ic.sh) f7f4f3fab0af4119bece19ff4a4360c3 等待执行完成后…

touch详讲

&#x1f3dd;️专栏&#xff1a;https://blog.csdn.net/2301_81831423/category_12872319.html &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 基本语法 主要功能 常用选项详解 1. …

UE5本地化和国际化语言

翻译语言 工具 - 本地化控制板 Localization Dashboard 修改图中这几个地方就可以 点击箭头处&#xff0c;把中文翻译成英语&#xff0c;如果要更多语言就点 添加新语言 最后点击编译即可 编译完&#xff0c;会在目录生成文件夹 设置界面相关蓝图中设置 切换本地化语言 必须在…

常见的显示器分辨率及其对应的像素数量

显示器的像素数量通常由其分辨率决定&#xff0c;分辨率表示为水平像素数乘以垂直像素数。 720P&#xff08;1280720&#xff09;&#xff1a; 像素数量&#xff1a;约92.16万特点&#xff1a;这是高清标准的一个分辨率&#xff0c;通常用于手机、平板电脑或小型显示器。900P&…

微信小程序实现登录注册

文章目录 1. 官方文档教程2. 注册实现3. 登录实现4. 关于作者其它项目视频教程介绍 1. 官方文档教程 https://developers.weixin.qq.com/miniprogram/dev/framework/路由跳转的几种方式&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab…

【C++】18.继承

文章目录 1.继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化 1.3 继承类模板 2.基类和派生类对象赋值转换3.继承中的作用域3.1 隐藏规则&#xff1a;3.2 考察继承作用域相关选择题 4.派生类的默认成员函数4…

PCL 分段线性函数

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 假设我们有一个分段线性函数,并且我们希望在某个区间内对这个函数进行均匀采样,生成一系列的点。相对通用一些的思路就是对这个函数进行参数化,方法有很多,这在其他的博客中也有提到,不过PCL也为我们提供了一种…

PostgreSQL学习笔记(二):PostgreSQL基本操作

PostgreSQL 是一个功能强大的开源关系型数据库管理系统 (RDBMS)&#xff0c;支持标准的 SQL 语法&#xff0c;并扩展了许多功能强大的操作语法. 数据类型 数值类型 数据类型描述存储大小示例值SMALLINT小范围整数&#xff0c;范围&#xff1a;-32,768 到 32,7672 字节-123INTE…

html + css 顶部滚动通知栏示例

前言 在现代网页设计中&#xff0c;一个吸引人的顶部滚动通知栏不仅能够有效传达重要信息&#xff0c;还能提升用户体验。通过使用HTML和CSS&#xff0c;我们可以创建既美观又功能强大的组件&#xff0c;这些组件可以在不影响网站整体性能的情况下提供实时更新或紧急通知。 本…

Bi-Encoder vs. Cross-Encoder

Bi-Encoder vs. Cross-Encoder Bi-Encoder 和 Cross-Encoder 是两种常见的模型架构&#xff0c;主要用于自然语言处理&#xff08;NLP&#xff09;中的文本匹配、问答、检索等任务。它们的主要区别在于如何处理输入文本以及计算相似度的方式。 1. Bi-Encoder&#xff08;双编…

excel如何将小数转换为百分比

在 Excel 中&#xff0c;将百分比格式的数字取消“%”并恢复为小数&#xff0c;可以按以下几种方法操作&#xff1a; 方法 1&#xff1a;直接更改格式 选中需要取消百分比格式的单元格。点击 **“开始”**选项卡中的 **“数字”**组。将单元格格式从“百分比”改为“常规”或“…

PyQt5 UI混合开发,控件的提升

PromoteLabelTest.py 提升的类 import sys from PyQt5.QtWidgets import QApplication, QWidget,QVBoxLayout,QTextEdit,QPushButton,QHBoxLayout,QFileDialog,QLabelclass PromoteLabel(QLabel):def __init__(self,parent None):super().__init__(parent)self.setText("…

A/B实验之置信检验(一):如何避免误判 (I类) 和漏报 (II类)

假设检验的依据&#xff1a;如何避免误判和漏报 A/B实验系列相关文章&#xff08;置顶&#xff09; 1.A/B实验之置信检验&#xff08;一&#xff09;&#xff1a;如何避免误判和漏报 2.A/B实验之置信检验&#xff08;二&#xff09;&#xff1a;置信检验精要 引言 在数据驱动…

Spring Boot整合Minio实现文件上传

Spring Boot整合Minio后&#xff0c;前端的文件上传有两种方式&#xff1a; 文件上传到后端&#xff0c;由后端保存到Minio 这种方式好处是完全由后端集中管理&#xff0c;可以很好的做到、身份验证、权限控制、文件与处理等&#xff0c;并且可以做一些额外的业务逻辑&#xf…

金融租赁系统助力行业转型与升级的创新之路

内容概要 在当今快速发展的商业环境中&#xff0c;金融租赁系统逐渐成为企业转型与升级的重要工具。它通过整合大数据与自动化技术&#xff0c;不仅提升了风险管理的准确性&#xff0c;还加快了审批流程&#xff0c;让企业在激烈的市场竞争中游刃有余。这个系统就像是一位聪明…

Postman接口测试02|接口用例设计

目录 六、接口用例设计 1、接口测试的测试点&#xff08;测试维度&#xff09; 1️⃣功能测试 2️⃣性能测试 3️⃣安全测试 2、设计方法与思路 3、单接口测试用例 4、业务场景测试用例 1️⃣分析测试点 2️⃣添加员工 3️⃣查询员工、修改员工 4️⃣删除员工、查询…

Python标准库之SQLite3

包含了连接数据库、处理数据、控制数据、自定义输出格式及处理异常的各种方法。 官方文档&#xff1a;sqlite3 --- SQLite 数据库的 DB-API 2.0 接口 — Python 3.13.1 文档 官方文档SQLite对应版本&#xff1a;3.13.1 SQLite主页&#xff1a;SQLite Home Page SQL语法教程&a…