拎清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逻辑接收到中断信号,应做出相关处理,如果不想中断线程逻辑的话,应当重置"中断信号"。
相关推荐
蛋蛋的就会顺顺的4 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
需要8264 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡5 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
伯恩bourne6 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
silvamux_7 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
省钱兄--zs7 小时前
深圳24小时自助健身房软硬件解决方案实战指南与开发流程详解
java·数据仓库·spring boot·小程序·架构
顽疲7 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
用户21296835261688 小时前
开源了一个 Java 多智能体 LLM 框架 Baton:一个依赖,把 Agent 循环、工具调用、记忆、编排全配齐
java·llm
helmsail8 小时前
05 管理活动与选品
java