拎清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逻辑接收到中断信号,应做出相关处理,如果不想中断线程逻辑的话,应当重置"中断信号"。
相关推荐
2501_9419820528 分钟前
深度对比:Java、Go、Python 实现企微外部群推送,哪个效率更高?
java·golang·企业微信
马猴烧酒.1 小时前
【面试八股|JAVA多线程】JAVA多线程常考面试题详解
java·服务器·数据库
sino爱学习1 小时前
高性能线程池实践:Dubbo EagerThreadPool 设计与应用
java·后端
风生u2 小时前
activiti7 详解
java
岁岁种桃花儿2 小时前
SpringCloud从入门到上天:Nacos做微服务注册中心(二)
java·spring cloud·微服务
Word码2 小时前
[C++语法] 继承 (用法详解)
java·jvm·c++
TT哇2 小时前
【实习 】银行经理端两个核心功能的开发与修复(银行经理绑定逻辑修复和线下领取扫码功能开发)
java·vue.js
逝水如流年轻往返染尘2 小时前
Java中的数组
java
java1234_小锋3 小时前
Java高频面试题:BIO、NIO、AIO有什么区别?
java·面试·nio
用户8307196840823 小时前
Java IO三大模型(BIO/NIO/AIO)超详细总结
java