0

我正在阅读关于线程的 oracle java 教程,我看到了这个例子

源代码:http : //docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

如果一个线程很长时间没有调用抛出 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 设置此标志。当线程通过调用静态方法 Thread.interrupted 检查中断时,中断状态被清除。一个线程用来查询另一个线程的中断状态的非静态 isInterrupted 方法不会改变中断状态标志。

按照惯例,任何通过抛出 InterruptedException 退出的方法都会在这样做时清除中断状态。然而,中断状态总是有可能被另一个线程调用中断立即再次设置。

现在我很困惑。什么时候发生?如果有中断,线程不应该收到 InterruptedException 吗?

什么时候有人可能会使用这些方法来检查他们的代码?Thread.interrupt(标志)是静态的,所以通过上面的检查,我们实际上检查是否有任何线程被中断?即使是这种情况,根据教程,当线程通过调用静态方法 Thread.interrupted 检查中断时,中断状态将被清除。任何通过抛出 InterruptedException 退出的方法都会在这样做时清除中断状态

那么,我错过了什么吗?或者这只是有用的,如果某个线程收到了一个中断,但没有检查它,或者没有抛出它?

4

3 回答 3

5

这是 Thread.interrupted 实现

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

private native boolean isInterrupted(boolean ClearInterrupted);

如您所见,它只能检查/重置当前线程的中断状态。如果它不是静态的,您可以在其他线程上调用它并重置它们的状态,这是 API 不允许的。

于 2013-01-03T04:26:45.640 回答
2

并非所有方法 in 都会Thread抛出InterrupedExceptions。它最常见于睡眠和等待,或任何耗时的方法。这就是 Java 实现它的方式。(sleep(...)native代码,所以我不能告诉你来源。)

例如:

try {
    Thread.sleep(1000); // one sec
} catch(InterruptedException e){
}

但是您不能强制在子句中包含一个简单的for循环。try..catch

如果您子类Thread化,则应遵循已发布的约定。


对于您的第二个问题,关于该static方法,这是内部代码:

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

所以你可以看到,它只是在当前线程中设置了一个实例。

于 2013-01-03T02:55:43.920 回答
1

很多时候一个线程正在做很多等待或阻塞。在几乎所有这些情况下,执行阻塞的方法都支持 InterruptedException。一些例子:

  1. Thread.sleep(毫秒);
  2. obj = arrayBlockingQueue.take();
  3. obj.wait();

参考文章指出的是,如果您的线程没有阻塞,这意味着没有支持 InterruptedException 的方法,那么您有责任检查您的线程是否已被中断。这是通过测试来完成的Thread.interrupted()

该方法Thread.interrupt()实际上不是静态的,而是从另一个线程调用以中断该线程。请参阅以下内容:

线程中断()

那有意义吗?

于 2013-01-03T03:11:03.110 回答