这些Java教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
有关Java SE 9和后续版本中更新的语言功能的摘要,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息,请参阅JDK发布说明。
一个中断是对一个线程的指示,告诉它停止当前的工作并做其他事情。程序员需要决定线程对中断的响应方式,但通常线程会被终止。本课程强调这种用法。
线程通过在要中断的线程的Thread
对象上调用interrupt
来发送中断。为了使中断机制正确工作,被中断的线程必须支持自己的中断。
一个线程如何支持自己的中断?这取决于它当前在做什么。如果线程经常调用会抛出InterruptedException
的方法,它只需在捕获到该异常后从run
方法中返回。例如,假设SleepMessages
示例中的中央消息循环在一个线程的Runnable
对象的run
方法中,那么可以修改为以下方式来支持中断:
for (int i = 0; i < importantInfo.length; i++) { // 暂停4秒 try { Thread.sleep(4000); } catch (InterruptedException e) { // 我们已经被中断:不再发送消息。 return; } // 打印消息 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()) { // 我们已经被中断:不再进行计算。 return; } }
在这个简单的例子中,代码只是检查中断并在收到中断时退出线程。在更复杂的应用程序中,抛出InterruptedException
可能更合理:
if (Thread.interrupted()) { throw new InterruptedException(); }
这样可以将中断处理代码集中在一个catch
子句中。
中断机制是使用一个称为中断状态的内部标志实现的。调用Thread.interrupt
会设置这个标志。当一个线程通过调用静态方法Thread.interrupted
来检查中断时,中断状态会被清除。非静态的isInterrupted
方法用于查询另一个线程的中断状态,它不会改变中断状态标志。
按照惯例,任何通过抛出InterruptedException
退出的方法在这样做时都会清除中断状态。然而,另一个线程调用interrupt
可能会立即再次设置中断状态。