首先根据单词意思可知interrupt(打断),又是线程中的方法,所以就是线程打断的意思,首先这个打断是在那里调用的呢?
需要先了解Thread线程中有一个方法isInterrupted用于获取线程是否被打断的状态,接着就来看看示例代码:
当线程休眠时打断
package com.juc.init.线程相关;
import java.util.concurrent.TimeUnit;
public class ThreadDemo6 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
t.interrupt();
System.out.println(t.isInterrupted());
}
}
输出结果:
可以发现输出了true表示该线程是被打断了,但是呢?这个真的是在线程休眠时被打断的吗?
显然是不一定的有可能在子线程还没有执行到sleep方法,main线程就执行了interrupt方法去打断子线程,所以可以通过给main线程打断方法执行前添加1秒的延时再去看看结果,代码如下:
package com.juc.init.线程相关;
import java.util.concurrent.TimeUnit;
public class ThreadDemo6 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
TimeUnit.SECONDS.sleep(1);
t.interrupt();
System.out.println(t.isInterrupted());
}
}
运行结果如下:
可以发现子线程睡眠的时候被打断真正的结果是抛出异常:Caused by: java.lang.InterruptedException: sleep interrupted
at java.base/java.lang.Thread.sleep(Native Method)
at java.base/java.lang.Thread.sleep(Thread.java:337)
at java.base/java.util.concurrent.TimeUnit.sleep(TimeUnit.java:446)
at com.juc.init.线程相关.ThreadDemo6.lambda$main$0(ThreadDemo6.java:9)
... 1 more
而不会去修改是否被打断的状态,所以结果放回的是false,接着就思考了除了sleep方法还有哪些情况也会出现类似情况,直接抛出异常呢?其实join方法wait方法也是类似的会取消线程的阻塞状态并且抛出InterruptedException
异常。
然而,除了以上三种情况,其他的情况只会将对应线程的isInterrupt状态设置为true,而不是直接打断线程执行。不直接终止线程的好处就是更安全,因为强制打断不会释放锁,遇到持有锁的线程并不会将锁释放掉,这样就会出现死锁的情况,所以通过只改isInterrupt的状态,相当于只通知对应的线程说:“你该被打断啦!有没有什么善后的工作还没有做的?快点做吧”;然后对应的线程判断isInterrupt的值发现为true并说到:“我还真的该被打断了,那我就先把锁释放了吧”,然后就拜拜啦将循环退出,锁释放掉。
总之,当有线程是sleep、join和wait的情况下,被interrupt会抛出异常,其他情况只会设置其isInterrupt()返回的状态为true。
今天分享的知识就这么多了,如果有讲解错误的地方还请指教。