①打断的是正在阻塞中的线程(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线程会阻塞住。