拎清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逻辑接收到中断信号,应做出相关处理,如果不想中断线程逻辑的话,应当重置"中断信号"。
相关推荐
程序猿小D1 小时前
[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+jsp实现的个人财务管理系统,推荐!
java·数据库·mysql·spring·毕业论文·ssm框架·个人财务管理系统
转转技术团队2 小时前
二奢仓店的静默打印代理实现
java·后端
钢铁男儿2 小时前
C# 接口(什么是接口)
java·数据库·c#
丶小鱼丶2 小时前
排序算法之【归并排序】
java·排序算法
上上迁2 小时前
分布式生成 ID 策略的演进和最佳实践,含springBoot 实现(Java版本)
java·spring boot·分布式
永日456703 小时前
学习日记-spring-day42-7.7
java·学习·spring
龙谷情Sinoam3 小时前
扩展若依@Excel注解,使其对字段的控制是否导出更加便捷
java
二十雨辰3 小时前
[尚庭公寓]07-Knife快速入门
java·开发语言·spring
掉鱼的猫3 小时前
Java MCP 实战:构建跨进程与远程的工具服务
java·openai·mcp
我爱Jack4 小时前
时间与空间复杂度详解:算法效率的度量衡
java·开发语言·算法