- 调用正常运行线程的isInterrupted方法返回false,即打断标记默认为false
- 调用正常运行中线程的interrupt方法会将打断标记置为true并抛出打断异常interrupted exception
- interrupt一个被sleep,wait,join锁住的方法,会将打断标记置为true,然后清除打断标记,然后throw interrupted exception
以上在interrupt源码前面注释里有写
但是代码中发现 ,打断一个sleep线程后调用isInterrupted查看打断标记,有时为false有时为true,而且为true的情况反而更多,false需要多次运行才会看到,如下,
--------开启一个线程sleep 10s,在主线程中第5s时候打断 并查看打断标记------
@Test
public void test1() throws InterruptedException {
Thread t1 = new Thread(()->{
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
t1.start();
TimeUnit.SECONDS.sleep(5);
t1.interrupt();
log.debug(" 打断状态: {}", t1.isInterrupted());
}
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at chapter3_Thread.Demo03_interrupt.lambda$test1$1(Demo03_interrupt.java:42)
at java.lang.Thread.run(Thread.java:748)
19:11:35.422 c.interrupt [main] - 打断状态: true
Process finished with exit code 0
结论,研究一下发现,调用t1.interrupt()后立即调用t1.isInterrupted(),有可能在t1还未完成清除打断标记并抛异常的时候就查看打断标记,此时仍然为true,
如果要得到稳定的false,即重置打断标记后的结果,应该在t1.interrupt()后, sleep一会,给点时间,有点像jvm启动后偏向锁延迟设置的意思。
@Test
public void test1() throws InterruptedException {
Thread t1 = new Thread(()->{
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
t1.start();
TimeUnit.SECONDS.sleep(5);
t1.interrupt();
// 留给清除打断标记时间
TimeUnit.SECONDS.sleep(1);
log.debug(" 打断状态: {}", t1.isInterrupted());
}
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at chapter3_Thread.Demo03_interrupt.lambda$test1$1(Demo03_interrupt.java:42)
at java.lang.Thread.run(Thread.java:748)
19:25:48.163 c.interrupt [main] - 打断状态: false
Process finished with exit code 0
另外加点思考,从第一个返回true的日志顺序看到,异常已经抛出,再查看打断标记还是true,而按源码描述的是先清除打断标记再抛异常,有点矛盾,这里好多方法都是native,也没法再往下看,以后遇到再说吧,mark