拎清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逻辑接收到中断信号,应做出相关处理,如果不想中断线程逻辑的话,应当重置"中断信号"。
相关推荐
counting money1 小时前
Spring AI Alibaba 从入门到实战:构建企业级 AI 应用
java·人工智能·spring
原野池予1 小时前
深入Java集合框架:数组与List互转底层原理剖析(JDK 8)
java·数据结构·list
Java成神之路-2 小时前
深入理解 HashMap 扩容时机:JDK 7 vs JDK 8 的设计差异与取舍
java·juc
李冰然2 小时前
深入Java集合框架:数组与List互转底层原理剖析(JDK 8)
java
竹枝溪2 小时前
MySQL进阶:约束、多表设计、多表查询与事务
java·数据库·mysql·事务·子查询·acid·多表查询
忍冬k2 小时前
DeepSeek harness安装指南
java·开发语言·数据结构·c++·算法
上玄code2 小时前
【Agent精讲】调一个LLMAPI背后的工程问题
java·开发语言·python·chatgpt
李冰然2 小时前
深入Java集合框架:ArrayList源码解析(JDK 8)
java
小小啊python2 小时前
IDEA中SpringBoot项目配置热部署
java·ide·intellij-idea·springboot·热部署
Java成神之路-3 小时前
Spring AI Alibaba 实现多轮对话记忆:ChatMemory 与 Redis 持久化实战
java·springaialibaba