如果在迭代中设置休眠一毫秒,有没有可能子线程接收到中断的时候没有在休眠导致无法正常抛出休眠中断异常?

来源:5-4 遇到阻塞

Panda_io

2019-08-16

图片描述
老师我测试了很多次,一毫秒也能抛出异常,但是不知道为什么,难道是因为我的CPU的的频率可达3.8GHz,执行一条指令太快大部分时间还是处于休眠期,所以接收到父线程中断信号的时候一定处于休眠期因此会抛出异常?

写回答

1回答

悟空

2019-08-16

小伙伴的问题很好,而且你还自己尝试运行不同的代码,有自己的思考,相信你一定能收获多多。

对于这个问题,问题不在于休眠时间的长短,而是在于“每次循环都有休眠,所以终究会运行到休眠的sleep代码,在sleep时才会抛出异常”。

具体解释如下:

我们先证明“问题不在于休眠时间的长短”,有两个办法可以证明。

方法1:我们把休眠时间设置到更短,比如TimeUnit.NANOSECONDS.sleep(1);,但是这也不会影响到抛出异常。

方法2:我们把代码执行时间拉长,比如每次循环都进行复杂计算,以便于发生中断时,程序大概率不在sleep期间,但是这也不会影响到抛出异常。

这是因为,interrupt是一个信号,这个信号并不是实时检测的,也不是每行代码都能检测的,在本例中,只有程序运行到sleep时,才能检测到线程被中断了,然后会抛出异常;而代码在计算其他内容时,比如执行if (num % 100 == 0)时,是无法感知到中断已经发生了的。所以问题不在于休眠时间的长短,而是在于“每次循环都有休眠,所以终究会运行到休眠的sleep代码,在sleep时才会抛出异常”。

这也是本类描述里写的“如果在执行过程中,每次循环都会调用sleep或wait等方法,那么不需要每次迭代都检查是否已中断”的原因,因为每一次循环中都包含sleep或wait等方法,所以我们就利用sleep或wait等方法帮我们检测中断,不过必须要等到执行到sleep或wait等方法时才能检测。

希望解释清楚你的疑惑了~

9
2
悟空
回复
Panda_io
不客气哦
2019-08-16
共2条回复

线程八大核心+Java并发原理及企业级并发解决方案

完整的并发知识网络+丰富的工作内容分享+50余道并发高频面试题

2512 学习 · 939 问题

查看课程