为什么线程 sleep 被中断后仍然继续执行?

 sleep方法小知识点:

sleep方法在使用后,需要通过try-catch (InterruptedException)或者throws InterruptedException,不可以在重写run方法时抛出InterruptedException,这样违背了重写方法的规则。

通过Thread.sleep(time)可以使得当前线程阻塞time时间(ms)

package createThread.cn.tedu.threaddemo.test;

import java.util.Scanner;

/**
 * 本例演示:线程在 sleep() 时被 interrupt() 中断,
 * 会抛出 InterruptedException 并清除线程的中断标志位。
 *
 * 因此在 catch 中不做任何处理(不 break,也不重新设置中断标志),
 * 外层 while (!cur.isInterrupted()) 会因为 isInterrupted() 返回 false 而继续执行,
 * 导致子线程无法按预期中断退出。
 *
 * 正确做法:
 * 1. 在 catch 中添加 break;
 * 2. 或者调用 Thread.currentThread().interrupt() 重新设置中断标志位。
 */

public class Test {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            Thread cur = Thread.currentThread();
            while (!cur.isInterrupted()) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
                System.out.println("thread 1");
            }
            System.out.println("子线程退出");
        });
        thread.start();

        System.out.println("输入0终止线程");
        Scanner scan = new Scanner(System.in);
        int i = scan.nextInt();
        if (i == 0) {
            thread.interrupt();
            System.out.println("主线程结束");
        }
    }
}
/**
 * sleep() 被中断后,必须手动处理异常(break 或重新设置中断标志),否则线程会“误以为”没有被中断,从而继续执行下去!
 */

我们的目标是在输入0后立即中断thread线程,通过在main线程中,输出0 判断后,使用thread的方法interrupt()方法,来中断thread线程,所以在thread线程中因为存在Thread.sleep()在被中断后catch到了 InterruptedException异常,在打印了异常输出后,立即break结束掉了thread的循环从而结束了run方法从而结束了thread线程。

但是我们将break语句注释掉后 

按理来说,我们在主线程main中输入了0,通过thread.interrupt()将thread中断了,为什么还能继续执行呢?

线程在 sleep() 时被 interrupt() 中断,
会抛出 InterruptedException 并清除线程的中断标志位。

因此在 catch 中不做任何处理(不 break,也不重新设置中断标志),
外层 while (!cur.isInterrupted()) 会因为 isInterrupted() 返回 false 而继续执行,
导致子线程无法按预期中断退出。

正确做法:
1. 在 catch 中添加 break;
2. 或者调用 Thread.currentThread().interrupt() 重新设置中断标志位。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值