我正在阅读关于线程的oracle java教程,我看到了这个例子
src: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在它执行时清除中断状态
所以,我错过了什么吗?或者这只是有用的,如果某个线程收到了一个中断,但没有检查它,或者没有抛出它?
答案 0 :(得分:5)
这是Thread.interrupted实现
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
private native boolean isInterrupted(boolean ClearInterrupted);
如您所见,它可以检查/重置当前线程的中断状态。如果它不是静态的,你可以在其他线程上调用它并重置它们的状态,这是API不允许的。
答案 1 :(得分:2)
并非Thread
中的所有方法都会抛出InterrupedException
。它主要是在睡眠和等待,或任何耗时的方法。这是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);
}
所以你可以在当前线程中看到它只是设置一个实例。
答案 2 :(得分:1)
很多时候,线程正在进行大量等待或阻止。在几乎所有这些情况下,执行阻塞的方法都支持InterruptedException。一些例子:
引用的文章指出的是,如果您的线程没有阻塞,意味着没有支持InterruptedException的方法,那么您有责任检查您的线程是否已被中断。这是通过测试Thread.interrupted()
来完成的。
方法Thread.interrupt()
实际上不是静态的,并且从另一个Thread调用以中断该线程。请参阅以下内容:
这有意义吗?