interrput打断的三种情况

①打断的是正在阻塞中的线程(sleep、wait、join),被打断的线程会抛出InterruptedException异常,打断标记会被清除。

@Slf4j(topic = "c.Test11")
public class Test11 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            log.debug("sleep...");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"t1");
        t1.start();
        Thread.sleep(1000);
        log.debug("interrupt");
        t1.interrupt();
        Thread.sleep(1000);
        log.debug("打断标记:{}", t1.isInterrupted());
    }
}
15:47:03.405 [t1] DEBUG c.Test11 - sleep...
15:47:04.408 [main] DEBUG c.Test11 - interrupt
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at cn.itcast.test.Test11.lambda$main$0(Test11.java:14)
	at java.lang.Thread.run(Thread.java:750)
15:47:05.427 [main] DEBUG c.Test11 - 打断标记:false
  • t1在sleep中被主线程打断,抛出InterruptedException异常
  • t1的打断标记被清除了,为false

②打断是正常运行的线程,线程的打断标记不会被清除,为true,线程可以通过判断打断标记,知道有人打断它了,但他停不停,什么时候停,由他自己说了算,他可以在知道自己被打断后,做一些善后工作再结束运行。

public class Test12 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (true) {
                boolean interrupted = Thread.currentThread().isInterrupted();
                if(interrupted) {
                    log.debug("被打断了,俺不玩了");
                    break;
                }
            }
        },"t1");
        t1.start();
        
        Thread.sleep(1000);
        log.debug("interrupt");
        t1.interrupt();
    }
}
16:00:18.645 [main] DEBUG cn.itcast.test.Test12 - interrupt
16:00:18.647 [t1] DEBUG cn.itcast.test.Test12 - 被打断了,俺不玩了
  • 主线程睡眠1s是为了保证t1线程已经开始运行
  • 主线程对t1线程打断后,t1线程可以通过isInterrupted()得到打断标记,知道自己被打断了,做一些善后工作

③打断的是park中的线程,线程会终止park状态,继续运行,但它的打断标记不会被清除,如果不手动清除,那么以后无法再次让该线程park,即该线程park失效。如果想让park再次生效,可以用Thread.interrupted()获取打断标记,它会在获取打断标记后将打断清除。

private static void test() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            log.debug("park...");
            LockSupport.park();
            log.debug("unpark...");
            log.debug("打断状态:{}", Thread.interrupted());
            
            LockSupport.park();
            log.debug("unpark...");
        },"t1");
        t1.start();
        
        Thread.sleep(1000);
        t1.interrupt();
    }
11:05:21.851 [t1] DEBUG c.Test14 - park...
11:05:22.858 [t1] DEBUG c.Test14 - unpark...
11:05:22.858 [t1] DEBUG c.Test14 - 打断状态:true
  • 因为打断标记被清除了,第二次执行park时,仍然有效,t1线程会阻塞住。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值