24

关于 Java 的InterruptedException有一些有趣的问题和答案,例如InterruptedException 的原因Java 中的 InterruptedException 处理。但是,他们都没有告诉我 InterruptedException 的可能来源。

像 SIGTERM、SIGQUIT、SIGINT 这样的操作系统信号呢?在命令行上按 CTRL-C 会产生 InterruptedException 吗?还有什么?

4

1 回答 1

33

您列出的所有内容都不会产生InterruptedException.

唯一可以中断线程的是调用Thread#interrupt(). 从第 17.2.3 节开始,JLS 对此事相对清楚:

17.2.3 中断

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

有关更多信息,请参阅有关中断的官方教程。具体来说:

线程通过调用要中断的线程interruptThread对象来发送中断。为了使中断机制正常工作,被中断的线程必须支持自己的中断。

...

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

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

这意味着它是一个只能通过调用设置的显式标志interrupt(),而不是由其他未知的外部事件触发。这在引发异常的各种方法中的异常描述中进一步暗示了这一点,例如(强调我的):

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


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

您看到的有关处理的许多注释和“警告”InterruptedException并不意味着它们可以完全自发地抛出,它们旨在鼓励精心设计的对象,这些对象可以在尚不知道的上下文中使用,interrupt()假定在哪里工作(真的,如果您正在创建可重用的对象,这些对象在未来情况下将是健壮的,那么您确实想假设它们可以自发抛出 - 即您永远不能保证您的代码有一天不会被期望的人使用中断工作)。

对于快速的一次性项目,只要您确定自己没有调用并且没有调用可以调用的东西,您实际上不需要担心对这些异常的特殊处理,但要注意的含义从长远来看,特别是如果您最终在其他上下文中重用该代码。interrupt()interrupt()

于 2014-11-11T02:10:19.250 回答