关于thread isInterrupted()方法,有时返回true和false不确定的问题

  1. 调用正常运行线程的isInterrupted方法返回false,即打断标记默认为false
  2. 调用正常运行中线程的interrupt方法会将打断标记置为true并抛出打断异常interrupted exception
  3. 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

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值