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

发布于 2024-12-17 17:20:31 字数 342 浏览 4 评论 0原文

我们假设线程 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相对绾红妆 2024-12-24 17:20:31

在第一种情况(“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 an InterruptedException being thrown. At this point, the thread's status flag represented by Thread#isInterrupted() will be cleared; calling Thread#isInterrupted() would return false. Since the InterruptedException 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:

  • either exit the current thread, or
  • call 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 via InterruptedException is if it caught the exception, ignored it, and called on some blocking method like Thread.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 throw InterruptedException.

Note that clearing the interruption status like that does not lose information so long as the clearing is immediately followed by throwing InterruptedException. A thrown InterruptedException 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 calling Thread#interrupt() after catching InterruptedException, restoring the interruption status for others to see.

See the book Java Concurrency in Practice for a more authoritative description of this protocol.

剑心龙吟 2024-12-24 17:20:31

检查线程的中断状态会清除状态标志;也就是说,引发 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文