4

我想澄清一下线程中断。

如果一个线程很长时间没有调用抛出一个InterruptedException的方法怎么办?然后它必须定期调用 Thread.interrupted,如果收到中断则返回 true。例如:

for (int i = 0; i < inputs.length; i++) {
    heavyCrunch(inputs[i]);
    if (Thread.interrupted()) {
        // We've been interrupted: no more crunching.
        return;
    }
}

当我调用Thread.interrupt()它抛出中断异常的方法时,为什么我需要这样做,if (Thread.interrupted())我会简单地这样做

try {
    for (int i = 0; i < inputs.length; i++) {
        heavyCrunch(inputs[i]);
        if (Thread.interrupted()) {
            // We've been interrupted: no more crunching.
            return;
        }
    }
} catch (InterruptedException ex) {
        ...
}
4

3 回答 3

4

当你调用Thread.interrupt()另一个线程时,会发生两件事:

  1. 该线程的中断标志已设置。
  2. 如果线程在方法 that 中被阻塞throws InterruptedException,该方法将立即抛出异常。

如果线程忙于一些抛出的代码InterruptedException,你不会得到任何异常。这就是为什么你需要检查if (Thread.interrupted()), 来检查标志。

在您的示例代码中,Java 编译器会抱怨无效catch块,因为块中的代码都不会trythrows InterruptedException

于 2014-03-12T15:27:56.027 回答
0

因为Thread.interrupted()正如记录的那样,根本不会抛出InterruptedException。它返回真或假,并清除调用设置的中断状态Thread.interrupt()。请注意,Thread.interrupt()也不会导致InterruptedException抛出 an 它只是设置中断状态。

于 2014-03-12T15:27:25.953 回答
0

在线程上调用中断不会直接导致线程抛出 InterruptedException。它所做的只是为该线程设置中断标志。sleep、wait 或 join 等方法可以在当前线程上引用该标志,以确定是否抛出 InterruptedException。

中断是合作的,被中断的线程决定如何响应;这样,线程可以进行任何需要做的清理工作,而不会在中途被击落。

您通常应该使用 Thread.isInterrupted() 因为这不会改变中断标志的值。Thread.interrupted()重置标志:

通过该方法清除线程的中断状态。换句话说,如果这个方法被连续调用两次,第二次调用将返回 false(除非当前线程再次被中断,在第一次调用清除其中断状态之后,第二次调用检查它之前)。

Thread.isInterrupted()没有:

测试此线程是否已被中断。线程的中断状态不受此方法的影响。

检查中断标志意味着您的线程可以检测它是否被中断而不必休眠或等待。Thread.isInterrupted() 和 Thread.interrupted() 都不会抛出 InterruptedException,使用它的代码会检查返回值。

此外,Thread.interrupt 不会抛出 InterruptedException。(并且抛出的任何异常都将在调用线程中,而不是在被中断的线程中。)interrupt 方法用于在另一个线程上设置中断标志。线程中断本身是没有意义的,线程可以返回。

于 2014-03-12T15:28:29.027 回答