关于Java的InterruptedException,有一些有趣的问题和答案,例如InterruptedException的原因和在Java中处理InterruptedException。然而,它们都没有告诉我InterruptedException可能的来源。
那么操作系统信号,如SIGTERM、SIGQUIT、SIGINT呢?在命令行上按下CTRL-C会产生InterruptedException吗?还有其他的来源吗?
关于Java的InterruptedException,有一些有趣的问题和答案,例如InterruptedException的原因和在Java中处理InterruptedException。然而,它们都没有告诉我InterruptedException可能的来源。
那么操作系统信号,如SIGTERM、SIGQUIT、SIGINT呢?在命令行上按下CTRL-C会产生InterruptedException吗?还有其他的来源吗?
你列出的任何事物都不会产生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()
的东西,您就不需要真正担心这些异常的特殊处理,但是请注意长远考虑的影响,尤其是如果您最终在其他上下文中重用该代码。