关于线程中断的理解

1,概述

首先,线程的中断是一种协作机制,什么是协作机制呢?每个线程都有一个boolean类型的中断状态,其他线程通过修改该线程的中断状态来控制该线程的中断;当中断时,会继续完成当前的线程任务。

2,Thread中断方法

interrupt():设置中断
isInterrupted():是否中断(返回是否已经设置中断状态)
interrupted():清除调用方当前线程的中断状态(静态方法)

public static boolean interrupted() {
	return currentThread().isInterrupted(true);
}

3,线程中断测试

class ThreadInterruptDemo {

    public static void main(String[] args) {
        System.out.println("进入测试");
        Thread thread = new Thread(() -> {
            Thread.currentThread().interrupt();
            System.out.println("线程中断 <- thread");
            System.out.println("thread.isInterrupted()=" + Thread.currentThread().isInterrupted() + " <- thread");
            int count = 0;
            while (true) {
                if (!Thread.currentThread().isInterrupted()) {
                    System.out.println("取消中断状态 <- thread");
                } else {
                    System.out.println("中断状态 <- thread");
                }
                count++;
                if (count == 1) {
                    boolean interrupted = Thread.interrupted();
                    System.out.println("通过interrupted()清空中断状态=" + interrupted + " <- thread");
                }
                if (count == 2) {
                    break;
                }
            }
        });
        thread.start();
        System.out.println("结束测试");
    }

}

由此可见,

  • 线程中断后,程序会继续完成当前任务,而且当任务完成后不会再开起程序;
  • 通过Thread.interrupted()方法是可以清除线程的中断状态的;

4,测试中遇到的问题

在main函数中调用Thread.interrupted()时,子线程一直没有清除中断状态;

答:经过查看代码之后,发现了interrupted()方法的原理为调用当前线程的取消中断,且为静态方法,所以只能在当前线程中调用才能清除本线程的中断状态;

5,InterruptedException异常处理解析

部分阻塞线程的注释如下:

InterruptedException – if any thread interrupted the current thread before or while the current thread was waiting. The interrupted status of the current thread is cleared when this exception is thrown.

InterruptedException异常的注释:

The following code can be used to achieve this effect:

if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();

当抛出InterruptedException异常时,中断状态将被清除;因此当通过try/catch捕获异常但不处理异常,就会造成线程继续执行,而不会按照原有的设想继续中断的情况;不过可以通过捕获异常来处理线程阻塞但需要中断的程序;具体如下:

@Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        try {
            Thread.sleep(100000); // 线程在此处阻塞,通过interrupt调用此线程中断
        } catch (InterruptedException e) {
            System.err.println("沉睡中被中断,且中断被清除");
        }
       //线程将继续执行
       System.err.println(Thread.currentThread().isInterrupted());
    }
}

可以通过如下方法传递中断:

@Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        try {
            Thread.sleep(100000);// 线程在此处阻塞,通过interrupt调用此线程中断
        } catch (InterruptedException e) {
            System.err.println("沉睡中被中断,且中断被清除");
            //传递中断
            Thread.currentThread().interrupt()
        }
       //中断状态
       System.err.println(Thread.currentThread().isInterrupted());
    }
}

且当线程已经处于中断状态时,Thread.sleep()会直接抛出异常

@Override
public void run() {
    Thread.currentThread().interrupt();
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        //当前线程已处于中断状态,会直接抛出异常
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值