当前位置: 首页 > news >正文

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.lryc.cn/news/517088.html

相关文章:

  • Tesseract5.4.0自定义LSTM训练
  • centOS7
  • HTML5 弹跳动画(Bounce Animation)详解
  • 4.1.3 串
  • 国产编辑器EverEdit - 两种删除空白行的方法
  • 1月7日星期二今日早报简报微语报早读
  • 随机置矩阵列为0[矩阵乘法pytorch版]
  • C# 中mysql数据库,已经在原有数据库升级数据库脚本,去管理可以一次,和多次执行的,nuget包
  • PCL 分段线性函数
  • 王静波页岩气:工厂蜕变的创业传奇
  • php反序列化 ctf例题演示 框架安全(TP,Yii,Laravel) phpggc生成框架利用pop
  • Koi技术教程-Tauri基础教程-第二节 Tauri的核心概念上
  • 入门网络安全工程师要学习哪些内容【2025年寒假最新学习计划】
  • vulnhub靶场【DC系列】之5
  • 前端面试题合集
  • 基于RK3568/RK3588大车360度环视影像主动安全行车辅助系统解决方案,支持ADAS/DMS
  • 基于 GEE Sentinel-1 数据集提取水体
  • Python判断、循环练习
  • 【简博士统计学习方法】第1章:4. 模型的评估与选择
  • 解密Navicat密码(Java)
  • 某聘__zp_stoken__参数逆向还原
  • 【数据可视化-11】全国大学数据可视化分析
  • 声音是如何产生的
  • 梯度下降方法
  • web3与AI结合-Sahara AI 项目介绍
  • Nginx——反向代理(三/五)
  • 环动科技平均售价波动下滑:大客户依赖明显,应收账款周转率骤降
  • 源网荷储:构建智慧能源生态的关键方案设计
  • 进程间通讯
  • STM32-笔记33-OLED实验