拎清Thread.interrupted()

1. 背景

在看java线程池代码时,经常看到如下代码:

java 复制代码
Thread.interrupted()
// wt是一个Thread对象
wt.isInterrupted()
wt.interrupt();

第一次有些傻傻分不清,长的都差不多。

2. 结论

先直接贴结果

java 复制代码
/**
 * 给Thread一个"中断信号",即把线程的中断status置为true。注意仅仅只是设置了状态。
 * 并不会中断逻辑,如果逻辑中有让线程处于blocked状态(如Object.wait()、Thread.sleep()等方法),就会抛出异常
 */
wt.interrupt(); 

/**
 * 返回线程的"中断状态"。
 */
wt.isInterrupted()

/**
 * 返回线程的"中断状态",并将线程的中断状态重新置为false。注意该方法是static方法
 */
Thread.interrupted()

3.验证

3.1.wt.interrupt() 设置中断信号

java 复制代码
public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(() -> {
        // 注意这里为了测试方便,写了死循环
        while (true){
        }
    });
    t.start();
    Thread.sleep(1000);
    System.out.println("first check interrupted status:::"+t.isInterrupted()); // 查询线程中断状态
    t.interrupt(); // 中断线程
    System.out.println("second check interrupted status:::"+t.isInterrupted()); // 查询线程中断状态
}

输出:

java 复制代码
first check interrupted status:::false
second check interrupted status:::true

此时线程t的中断状态已经是true了,但它的逻辑并不会中断 ,线程里的代码还是一直在继续执行的。一般来说,会在代码中使用wt.isInterrupted()来判断线程的中断状态,并做出响应的处理。到这里应该就知道wt.interrupt(); wt.isInterrupted()方法的效果了。

3.2.wt.interrupt() 执行线程自动抛出异常

线程的"中断信号"被置为true后,如果代码中有让线程处于blocked状态的逻辑(如Object.wait()、Thread.sleep()等方法),就会抛出异常,通知线程必须做出响应的处理,如下:

java 复制代码
public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(() -> {
        int i = 0;
        while (i < 10){
            while (true){ // 做一个死循环,要不然看不到效果
                // 中断信号为true时,结束死循环
                if(Thread.currentThread().isInterrupted()){
                    break;
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // 线程状态状态置为true后,会自动抛出异常并把中断状态修改为false
                // 个人理解,重新置为false,这是为告诉外面的线程,我已经处理过了。
                System.out.println("线程中断异常:"+e.getMessage());
            }
            i = i + 10;
        }
    });
    t.start();
    System.out.println("first check interrupted status:::"+t.isInterrupted()); // 查询线程 中断状态
    t.interrupt(); // 中断线程
    System.out.println("second check interrupted status:::"+t.isInterrupted()); // 查询线程 中断状态
    Thread.sleep(1000);
    System.out.println("third check interrupted status:::"+t.isInterrupted()); // 查询线程 中断状态
}

输出:

java 复制代码
first check interrupted status:::false
// 此时线程中断信号被置为true,由于写了死循环,还未执行到Thread.sleep(1000),故未抛出异常
second check interrupted status:::true
线程中断异常:sleep interrupted
// 抛出中断异常后,又自动把中断信号置为了false
third check interrupted status:::false

3.3.Thread.interrupted()

返回当前线程的中断状态,并将中断状态置为false。

java 复制代码
public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(() -> {
        while (true) {
            if (Thread.interrupted()) {
                System.out.println("线程已收到中断状态!");
                break;
            }
        }
    });
    t.start();
    System.out.println("first check interrupted status:::" + t.isInterrupted()); // 查询线程 中断状态
    t.interrupt(); // 中断线程
    System.out.println("second check interrupted status:::" + t.isInterrupted()); // 查询线程 中断状态
    Thread.sleep(1000);
    System.out.println("third check interrupted status:::" + t.isInterrupted()); // 查询线程 中断状态
}

输出:

java 复制代码
first check interrupted status:::false
second check interrupted status:::true // 线程中断信号置为true
线程已收到中断状态! // Thread.interrupted()返回true,检测到线程被中断
再次检测线程中断状态:false // Thread.interrupted()执行后,重新将中断状态置为true
third check interrupted status:::false

4.总结

  1. 到这里,大家发现,这三个方法都没有强制终止线程的执行。经过一番度娘了解,说外部强制中止一个Thread是不安全的,所以java中也把Thread.stop()相关方法打上了@Deprecated标记。
  2. 所以一般都是外部给Thread一个中断信号,然后由Thread自己根据"中断信号"来做出相应的处理。Thread逻辑接收到中断信号,应做出相关处理,如果不想中断线程逻辑的话,应当重置"中断信号"。
相关推荐
努力成为包租婆35 分钟前
uniapp--原生插件开发
java·数据库·uni-app
海南java第二人2 小时前
Spring MVC核心流程深度解析:从请求到响应的完美掌控
java·springmvc
未来之窗软件服务2 小时前
幽冥大陆(一百10)PHP打造Java的Jar安全——东方仙盟筑基期
java·php·phar·仙盟创梦ide·东方仙盟
程序猿_极客5 小时前
【2025 年最新版】Java JDK 安装与环境配置教程(附图文超详细,Windows+macOS 通用)
java·开发语言·windows·macos·jdk
猫头虎5 小时前
macOS 双开/多开微信WeChat完整教程(支持 4.X 及以上版本)
java·vscode·macos·微信·编辑器·mac·脚本
二哈喇子!8 小时前
Java开发工具——IDEA(修改全局配置,提升工作效率)
java·编辑器·intellij-idea
强子感冒了8 小时前
Java网络编程学习笔记,从网络编程三要素到TCP/UDP协议
java·网络·学习
二哈喇子!8 小时前
SpringBoot项目右上角选择ProjectNameApplication的配置
java·spring boot
sin22018 小时前
MyBatis的执行流程
java·开发语言·mybatis
二哈喇子!8 小时前
基于Spring Boot框架的车库停车管理系统的设计与实现
java·spring boot·后端·计算机毕业设计