千家信息网

如何理解Volatile+Interrupt是停止线程优雅的姿势

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容主要讲解"如何理解Volatile+Interrupt是停止线程优雅的姿势",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何理解Volatile+
千家信息网最后更新 2026年10月31日如何理解Volatile+Interrupt是停止线程优雅的姿势

本篇内容主要讲解"如何理解Volatile+Interrupt是停止线程优雅的姿势",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何理解Volatile+Interrupt是停止线程优雅的姿势"吧!

使用stop方法

调用stop方法,会让正在运行的线程直接中止,有可能会让一些清理性的工作得不到完成。并且stop已经被标记为废弃的方法,不建议使用。

正确的使用姿势是使用两阶段终止的模式,即一个线程发送终止指令,另一个线程接收指令,并且决定自己在何时停止。

使用标志位

public class RunTask {      private volatile boolean stopFlag;     private Thread taskThread;      public void start() {         taskThread = new Thread(() -> {             while (!stopFlag) {                 System.out.println("doSomething");             }         });         taskThread.start();     }      public void stop() {         stopFlag = true;     } }

「stopFlag上加volatile是保证可见性。我这个例子用了while循环不断判断,如果项目中用不到while的话,可以在关键节点判断,然后退出run方法即可」

使用interrupt方法

假如我们的任务中有阻塞的逻辑,如调用了Thread.sleep方法,如何让线程停止呢?

从线程状态转换图中寻找答案

从图中可以看到如果想让线程进入终止状态的前提是这个线程处于运行状态。当我们想要终止一个线程的时候,如果此时线程处于阻塞状态,我们如何把它转换到运行状态呢?

我们可以通过调用Thread#interrupt方法,将阻塞状态的线程转换到就绪状态,进入由操作系统调度成运行状态,即可终止。

那线程在运行状态中调用interrupt方法,会发生什么呢?

public class RunTaskCase1 {      private Thread taskThread;      public void start() {         taskThread = new Thread(() -> {             while (true) {                 System.out.println("doSomething");             }         });         taskThread.start();     }      public void stop() {         taskThread.interrupt();     } }

依次调用start方法和stop方法,发现线程并没有停止。

「其实当线程处于运行状态时,interrupt方法只是在当前线程打了一个停止的标记,停止的逻辑需要我们自己去实现」

「Thread类提供了如下2个方法来判断线程是否是中断状态」

  1. 鸿蒙官方战略合作共建--HarmonyOS技术社区

  2. isInterrupted

  3. interrupted

这2个方法虽然都能判断状态,但是有细微的差别

@Test public void testInterrupt() throws InterruptedException {     Thread thread = new Thread(() -> {         while (true) {}     });     thread.start();     TimeUnit.MICROSECONDS.sleep(100);     thread.interrupt();     // true     System.out.println(thread.isInterrupted());     // true     System.out.println(thread.isInterrupted());     // true     System.out.println(thread.isInterrupted()); }
@Test public void testInterrupt2() {     Thread.currentThread().interrupt();     // true     System.out.println(Thread.interrupted());     // false     System.out.println(Thread.interrupted());     // false     System.out.println(Thread.interrupted()); }

「isInterrupted和interrupted的方法区别如下」

Thread#isInterrupted:测试线程是否是中断状态,执行后不更改状态标志 Thread#interrupted:测试线程是否是中断状态,执行后将中断标志更改为false

「所以此时我们不需要自已定义状态,直接用中断标志即可,之前的代码可以改为如下」

public class RunTaskCase2 {      private Thread taskThread;      public void start() {         taskThread = new Thread(() -> {             while (!Thread.currentThread().isInterrupted()) {                 System.out.println("doSomething");             }         });         taskThread.start();     }      public void stop() {         taskThread.interrupt();     } }

当线程处于阻塞状态时,调用interrupt方法,会抛出InterruptedException,也能终止线程的执行

「注意:发生异常时线程的中断标志为会由true更改为false。」

所以我们有如下实现 当线程处于运行状态:用自己定义的标志位来退出 当线程处于阻塞状态:用抛异常的方式来退出

public class RunTaskCase3 {      private volatile boolean stopFlag;     private Thread taskThread;      public void start() {         taskThread = new Thread(() -> {             while (stopFlag) {                 try {                     System.out.println("doSomething");                     TimeUnit.MICROSECONDS.sleep(100);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         });         taskThread.start();     }      public void stop() {         stopFlag = true;         taskThread.interrupt();     } }

当然也可以一直用中断标志来退出,「注意,当发生异常的时候需要重置中断标志位」。

public class RunTaskCase4 {      private Thread taskThread;      public void start() {         taskThread = new Thread(() -> {             while (!Thread.currentThread().isInterrupted()) {                 try {                     System.out.println("doSomething");                     TimeUnit.MICROSECONDS.sleep(100);                 } catch (InterruptedException e) {                     // 重置中断标志位为true                     Thread.currentThread().interrupt();                     e.printStackTrace();                 }             }         });         taskThread.start();     }      public void stop() {         taskThread.interrupt();     } }

到此,相信大家对"如何理解Volatile+Interrupt是停止线程优雅的姿势"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

线程 状态 方法 标志 运行 阻塞 姿势 优雅 内容 指令 时候 标记 逻辑 图中 学习 测试 实用 更深 细微 循环不断 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡网 互联网科技公司排名 互联网科技公司简介 广州大一互联网络科技有限公司 科技金融是不是互联网金融 疫情对互联网科技公司影响 贷财互联网科技 广州紫鲸互联网科技 卓越科技互联网 招聘 哈尔滨新华互联网科技学院 互联网科技实习生岗位职责 互联网科技项目计划书材料类 科技类公司包括互联网吗 华中科技大学互联网的牛人 珠海东科互联网科技有限公司 互联网科技职业技能培训学校 山东蛋芒互联网科技有限公司 现代互联网科技公司 互联网金融金融科技 利用互联网等科技手段 上海挚品互联网科技有限公司 A股互联网金融科技公司 互联网金融公司科技 互联网科技logo设计 上海万想互联网科技 青岛中康互联网医疗科技有限公司 互联网在线教育科技创业 上海科技产业互联网平台 上海钢联属于互联网科技股吗 西安左小互联网科技有限公司
0