InterruptedException: 是什么导致了它?

29
1个回答

37

你列出的任何事物都不会产生InterruptedException异常。

唯一可以中断线程的是调用Thread#interrupt()方法。JLS在第17.2.3节相对清楚地说明了这一点:

17.2.3 中断

中断操作发生在调用Thread.interrupt以及定义为调用它的方法时,例如ThreadGroup.interrupt

有关中断的更多信息,请参见中断的官方教程。特别是:

线程通过在要中断的线程的Thread对象上调用interrupt来发送中断。为使中断机制正常工作,被中断的线程必须支持其自身中断。

...

中断机制使用一个称为“中断状态”的内部标志来实现。调用Thread.interrupt会设置此标志。当线程通过调用静态方法Thread.interrupted检查中断时,中断状态被清除。非静态的isInterrupted方法用于查询另一个线程的中断状态,不会更改中断状态标志。

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

暗示是它是一个明确的标志,只有通过调用interrupt()才能设置,而不是由其他未知的外部事件触发。这在抛出它的各种方法的描述中进一步暗示,例如(重点是我的)

InterruptedException - 如果任何线程中断了当前线程。当抛出此异常时,当前线程的中断状态将被清除。


总体上,中断系统的目的是为提供一个共同的、明确定义的框架,允许线程在其他线程中中断任务(可能是耗时的任务)。虽然您可以在自己的应用程序中使用显式逻辑实现类似的功能,但是拥有这个明确定义的机制允许独立的类(例如JDK、其他第三方代码、您自己代码中的其他独立类)以一致的方式提供这种功能。

关于处理InterruptedException的许多注释和“警告”并不意味着它们可以被完全自发地抛出,而是意味着鼓励设计良好的对象,可以在尚未知道的上下文中使用,其中会假定interrupt()起作用(因此,如果您正在创建可重用对象,将在未来的情况下具有鲁棒性,则确实希望假定它们可以自发地抛出 - 也就是说,不能保证您的代码不会被某个日子预计中断工作的人使用)。

对于快速的临时项目,只要您确定自己没有调用interrupt()并且没有调用可能会调用interrupt()的东西,您就不需要真正担心这些异常的特殊处理,但是请注意长远考虑的影响,尤其是如果您最终在其他上下文中重用该代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接