中断(interrupt)表明线程应该停止正在执行的操作并执行其他操作。 完全由程序员决定线程如何响应中断,但是线程终止是很常见的。 这是本课中强调的用法。
线程通过在要中断线程的Thread
对象上调用interrupt
,来发送中断。 为了使中断机制正常工作,被中断的线程必须支持自己的中断。
支持中断
线程如何支持自己的中断?这取决于它当前正在做什么。如果线程经常调用抛出InterruptedException
的方法,则在捕获该异常后,它仅从run
方法返回。例如,假设SleepMessages
示例中的中央消息循环位于线程Runnable
对象的run
方法中。然后可以对其进行如下修改,以支持中断:
for (int i = 0; i < importantInfo.length; i++) {
// Pause for 4 seconds
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
// Print a message
System.out.println(importantInfo[i]);
}
许多抛出InterruptedException
的方法(例如sleep
)旨在取消其当前操作,并在收到中断时立即返回。
如果线程长时间运行而没有调用抛出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;
}
}
在这个简单的示例中,代码仅测试了中断,如果已接收到中断,则退出线程。在更复杂的应用程序中,抛出InterruptedException
可能更有意义:
if (Thread.interrupted()) {
throw new InterruptedException();
}
中断状态标志
中断机制使用内部标志(称为中断状态(interrupt status))实现。调用Thread.interrupt
设置此标志。当线程通过调用静态方法Thread.interrupted
检查中断时,将清除中断状态。一个线程用于查询另一线程的中断状态的非静态方法isInterrupted
不会更改中断状态标志。
按照惯例,任何通过抛出InterruptedException
而退出的方法都会清除中断状态。但是,总是有可能通过另一个线程调用interrupt
,再次立即设置中断状态。