在线程运行时中断它;下一次中断的影响是什么?
我们假设线程 t1 正在运行(即不处于睡眠、等待或加入状态)。另一个线程 t2 中断 t1。 Javadoc 表示将设置 t1 的中断状态。
假设 t1 稍后进入睡眠、等待或加入状态。会发生什么?
i) 由于线程 t1 处于中断状态,因此它是否会自动引发 InterruptedException
?
假设 t1 仍处于睡眠、等待或加入状态。让我们想象 t2 再次中断 t1:
ii) 线程 t1 是通过 InterruptedExecution 引发的还是需要首先通过调用 Interrupted() 来清除其中断状态?
Java 对此有官方立场吗?谢谢。
Let's assume thread t1 is running (i.e. not in a sleep, wait or join state). Another thread t2 interrupts t1. The Javadoc says t1's interrupted status will be set.
Let's assume t1 falls into sleep, wait or join status later. What happens?
i) Is thread t1 automatically raised with an InterruptedException
since it had an interrupted status?
Let's assume t1 is still into a sleep, wait or join state. Let's imagine t2 interrupts t1 again:
ii) Is thread t1 raised with an InterruptedExecution
or does it need to clear its interruption status with a call to interrupted()
first?
Is there an official Java position on this one? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在第一种情况(“i”)中,是的,睡眠线程将通过抛出
InterruptedException
的方式从对 Thread#sleep() 的调用中弹出。此时,线程的状态标志由Thread#isInterrupted()
将被清除;调用 Thread#isInterrupted() 将返回 false。由于InterruptedException
正在运行,因此该消息已发送给所有传递调用者。然后,调用者有责任捕获该异常并执行以下两件事之一:
Thread#interrupt()
在当前线程上(即Thread.currentThread().interrupt()
)当您说线程“t1”“仍处于睡眠、等待或加入状态”时,这是在初始调用后唯一可能出现的情况通过
InterruptedException
退出的Thread#sleep()
是指它捕获了异常,忽略了它,并调用了一些阻塞方法,例如Thread.sleep() 在线程“t2”之前再次执行有机会再次打断它。
如果线程“t2”再次中断线程“t1”而“t1”当前在可中断方法调用上被阻塞,“t1”的调用将再次退出并出现
InterruptedException代码>.否则,线程的中断标志将被设置以供以后检测。
每次调用
Thread#interrupt()
时,该目标线程的中断状态将被设置为“true”,这意味着该线程自其 >中断状态最后被清除。下次被中断的线程尝试对可中断方法进行阻塞调用时,该线程的中断状态将被清除,并且该方法将抛出 InterruptedException。请注意,只要清除后立即抛出 InterruptedException,像这样清除中断状态就不会丢失信息。抛出的
InterruptedException
最好解释为:“该线程在之前的某个时刻设置了其中断状态,现在您有责任做出反应,通常是警告后续调用者有意的中断。”您可以通过在捕获 InterruptedException 后调用 Thread#interrupt() 来实现后一个目标,恢复中断状态以供其他人查看。请参阅Java并发实践一书,了解该协议的更权威的描述。
In the first case ("i"), yes, the sleeping thread will get popped out of its call to
Thread#sleep()
by way of anInterruptedException
being thrown. At this point, the thread's status flag represented byThread#isInterrupted()
will be cleared; callingThread#isInterrupted()
would return false. Since theInterruptedException
is in flight, the message has been sent to all transitive callers.It's then the callers' responsibility to catch that exception and do one of two things:
Thread#interrupt()
on the current thread (that is,Thread.currentThread().interrupt()
)When you say that thread "t1" is "still in a sleep, wait, or join state," the only way it could be so after its initial call to
Thread#sleep()
exited viaInterruptedException
is if it caught the exception, ignored it, and called on some blocking method likeThread.sleep()
again before thread "t2" has a chance to interrupt it a second time.If thread "t2" were to interrupt thread "t1" again while "t1" is currently blocked on an interruptible method call, "t1"'s call will again exit with an
InterruptedException
. Otherwise, the thread's interruption flag will be set for later detection.Every time one calls
Thread#interrupt()
, the the interruption status of that target thread will be set to "true," meaning the thread has been interrupted since its interruption status was last cleared. The next time that the interrupted thread attempts to make a blocking call to an interruptible method, the thread's interruption status will be cleared and the method will throwInterruptedException
.Note that clearing the interruption status like that does not lose information so long as the clearing is immediately followed by throwing
InterruptedException
. A thrownInterruptedException
is best interpreted as, "This thread had its interruption status set at some point prior, and now it's your responsibility to react and, usually, to warn subsequent callers of the intended interruption." You achieve the latter objective by callingThread#interrupt()
after catchingInterruptedException
, restoring the interruption status for others to see.See the book Java Concurrency in Practice for a more authoritative description of this protocol.
检查线程的中断状态会清除状态标志;也就是说,引发 InterruptedException 的代码正在清除状态,就像您自己的手动采样状态的代码一样。
Checking the interrupted state of a thread clears the state flag; that is to say, the code that raises an
InterruptedException
is clearing the state, as your own code that manually samples the state.