【问题标题】:Interrupting a thread while it is running; what is the impact of the next interruption?在线程运行时中断它;下一次中断有什么影响?
【发布时间】:2025-12-30 23:10:11
【问题描述】:

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

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

i) 线程 t1 是否因为处于中断状态而自动使用 InterruptedException 引发?

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

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

在这方面有官方的 Java 立场吗?谢谢。

【问题讨论】:

    标签: java multithreading interruption


    【解决方案1】:

    在第一种情况下(“i”),是的,睡眠线程将通过抛出InterruptedException 的方式从其对Thread#sleep() 的调用中弹出。此时,Thread#isInterrupted()所代表的线程状态标志将被清除;调用 Thread#isInterrupted() 将返回 false。由于InterruptedException 处于飞行状态,消息已发送给所有传递调用者。

    然后调用者有责任捕获该异常并执行以下两项操作之一:

    • 要么退出当前线程,要么
    • 在当前线程上调用Thread#interrupt()(即Thread.currentThread().interrupt()

    当您说线程“t1”“仍处于睡眠、等待或加入状态”时,在通过 InterruptedException 退出对 Thread#sleep() 的初始调用后,唯一可能的情况是它是否捕获了异常,忽略它,并在线程“t2”有机会再次中断它之前再次调用一些阻塞方法,如Thread.sleep()

    如果线程“t2”再次中断线程“t1”当“t1”当前被可中断方法调用阻塞时,“t1”的调用将再次以InterruptedException退出.否则,将设置线程的中断标志以供以后检测。

    每次调用Thread#interrupt(),该目标线程的中断状态都会被设置为“true”,这意味着线程在中断状态之后就被中断了> 上次清除。下一次被中断线程尝试对可中断方法进行阻塞调用时,线程的中断状态将被清除,该方法将抛出InterruptedException

    注意,像这样清除中断状态不会丢失信息,只要清除后立即抛出InterruptedException。抛出的InterruptedException 最好解释为:“此线程的中断状态 在之前的某个时间点设置,现在您有责任做出反应,并且通常警告后续调用者预期的中断。 "您可以通过在捕获InterruptedException 后调用Thread#interrupt() 来实现后一个目标,恢复中断状态 以供其他人查看。

    参见Java Concurrency in Practice一书,了解该协议更权威的描述。

    【讨论】:

      【解决方案2】:

      检查线程的中断状态会清除状态标志;也就是说,引发InterruptedException 的代码正在清除状态,就像您自己的代码手动采样状态一样。

      【讨论】:

        最近更新 更多