假设线程t1正在运行(即不处于睡眠,等待或加入状态)。另一个线程t2中断t1。 Javadoc说t1的中断状态将被设置。
让我们假设t1进入睡眠状态,稍后等待或加入状态。会发生什么?
i)线程t1是否因为状态中断而自动引发InterruptedException
?
假设t1仍处于睡眠,等待或加入状态。让我们假设t2再次中断t1:
ii)线程t1是用InterruptedExecution
引发还是需要首先调用interrupted()
来清除其中断状态?
这个问题上是否有正式的Java职位?感谢。
答案 0 :(得分:2)
在第一种情况下(“i”),是的,睡眠线程将通过抛出Thread#sleep()
从InterruptedException
的调用中弹出。此时,将清除由Thread#isInterrupted()
表示的线程状态标志;调用Thread#isInterrupted()
将返回false。由于InterruptedException
正在进行中,因此该消息已发送给所有可传递的呼叫者。
然后调用者有责任捕获该异常并执行以下两项操作之一:
Thread#interrupt()
(即Thread.currentThread().interrupt()
)如果您说线程“t1”仍处于“休眠,等待或加入状态”,那么在通过Thread#sleep()
退出InterruptedException
的初始调用之后,唯一可能的方法是如果它捕获了异常,则忽略它,并在线程“t2”有机会再次中断它之前再次调用Thread.sleep()
之类的阻塞方法。
如果线程“t2”再次中断线程“t1”而“t1”当前在可中断方法调用上被阻止,则“t1”的调用将再次以{{1}退出}}。否则,将设置线程的中断标志以供以后检测。
每次调用InterruptedException
时,该目标线程的中断状态将被设置为“true”,这意味着线程已经被中断中断状态< / em>最后被清除。下次中断的线程尝试对可中断方法进行阻塞调用时,线程的中断状态将被清除,方法将抛出Thread#interrupt()
。
请注意,只要清除后立即抛出InterruptedException
,清除中断状态就不会丢失信息。抛出的InterruptedException
最好被解释为,“此线程在之前的某个时刻设置了中断状态,现在您有责任做出反应,并且通常会警告后续呼叫者中断“。在捕获InterruptedException
后调用Thread#interrupt()
,恢复中断状态供其他人查看时,您可以实现后一目标。
有关此协议的更权威说明,请参阅书籍Java Concurrency in Practice。
答案 1 :(得分:1)
检查线程的中断状态会清除状态标志;也就是说,引发InterruptedException
的代码正在清除状态,作为您自己的手动采样状态的代码。