在线程运行时中断线程;下次中断的影响是什么?

时间:2011-11-24 11:54:31

标签: java multithreading interruption

假设线程t1正在运行(即不处于睡眠,等待或加入状态)。另一个线程t2中断t1。 Javadoc说t1的中断状态将被设置。

让我们假设t1进入睡眠状态,稍后等待或加入状态。会发生什么?

i)线程t1是否因为状态中断而自动引发InterruptedException

假设t1仍处于睡眠,等待或加入状态。让我们假设t2再次中断t1:

ii)线程t1是用InterruptedExecution引发还是需要首先调用interrupted()来清除其中断状态?

这个问题上是否有正式的Java职位?感谢。

2 个答案:

答案 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的代码正在清除状态,作为您自己的手动采样状态的代码。