线程中断之-interrupt()、isInterrupted()、interrupted()

线程中断是线程通讯的一种手段,设置线程的中断标识并不意味着该线程会立即挂起,相反,如果该线程对自己的中断标识的变化不采取任何手段,则该中断标识将没有任何意义,程序将继续向下运行。

主要涉及到三个主要API。

1. interrupt()

1.1 测试中断之后线程是否会继续执行
public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(() -> {
            for (; ; ) {
                System.out.println(Thread.currentThread().getName() + " is saying hello");
            }
        });

        //启动thread线程
        thread.start();

        //main线程首先等待1S,目的是让thread线程首先启动
        Thread.sleep(1000);

        //设置中断标识
        thread.interrupt();
    }

运行结果:程序会不断进行打印,并不会终止

1.2 线程中断标志的正确使用方法

通常在两个场景下线程会被设置中断标志

  1. 其他线程认为该线程应该终止当前的操作
public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(() -> {
            //如果当前线程没有被设置中断标志,则该线程继续运行
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println(Thread.currentThread().getName() + " is go on working");
            }
        });

        //启动thread线程
        thread.start();

        //main线程首先等待1S,目的是让thread线程首先启动
        Thread.sleep(1000);

        //设置中断标识
        thread.interrupt();
    }

运行结果:1S之后程序会停止

该程序和上一段程序的唯一区别就在于for循环变成了while循环,并且在while循环中不断地检查当前线程是否被设置中断标志,这也是isInterrupted()的标准使用方法。

  1. 打断目标线程的阻塞状态(wait,join,sleep导致),强制抛出异常并返回
 public static void main() throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                System.out.println("线程即将进入睡眠...");
                Thread.sleep(1000000);
                System.out.println("线程被唤醒...");
            } catch (InterruptedException e) {
                System.out.println("线程睡眠过程中被打断");
                //使该线程继续向下运行
            }
            System.out.println("其他业务被执行");
        });

        //启动thread线程
        thread.start();

        //main线程首先等待1S,目的是让thread线程首先启动
        Thread.sleep(1000);

        //打断子线程sleep状态,抛出异常强行退出
        thread.interrupt();

    }

运行结果如下:
在这里插入图片描述

2. boolean isInterrupted()

检测当前线程是否被设置中断标志,是则返回true,否则返回false
相比于接下来介绍的interrupted(),该方法更加常用
在这里插入图片描述
查看该函数源码发现,其调用的子函数带有一个boolean类型的参数,表示是否清除中断标记。
因此isInterrupted()函数仅仅返回中断标志,不会清除中断标志。

3. interrupted()

查看源码
在这里插入图片描述
该函数和isInterrupted()有3点不同

  1. 该方法为static方法,可以直接利用Thread调用
  2. 该方法返回的调用该方法的当前线程的终端状态,而不是被调用线程的中断状态
  3. 该方法的会清除线程的中断标记

下面通过一个例子更好的理解isInterrupted()和interrupted()之间的区别(例子摘取自《并发编程之美》)

public static void compare() throws InterruptedException {
        Thread thread = new Thread(() -> {
            for (; ; ) {

            }
        });

        //启动线程
        thread.start();

        //设置中断标志
        thread.interrupt();

        //1.获取中断标志
        System.out.println("isInterrupted:" + thread.isInterrupted());

        //2.获取中断标志并重置
        System.out.println("interrupted:" + thread.interrupted());

        //3.获取中断标志并重置
        System.out.println("interrupted:" + Thread.interrupted());

        //4.获取中断标志
        System.out.println("isInterrupted:" + thread.isInterrupted());
        
        thread.join();

    }

大家不妨先自己理解一下给出自己的答案
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

输出结果
在这里插入图片描述

第一个打印结果是true应该是很容易理解的,因为thread线程被主线程设置了中断标记,因此isinterrupted()为true


第二个打印结果为false可能很多人不理解了,这是因为上文说过的interrupted()这个函数获取的是当前线程的终端状态,因为当前线程是主线程,所以和thread无关(虽然实在thread上调用的该函数)


第三个打印结果同理,由此可见,这里thread.interrupted()和Thread.interrupted()是等价的


第四个打印结果为true,因为isInterrupted()获取的还是thread的中断状态

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝉沐风的码场

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值