InterruptedException:是什么原因造成的?

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

那些OS信号如SIGTERM,SIGQUIT,SIGINT? 在命令行上按CTRL-C会产生InterruptedException吗? 还有什么?

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

唯一可以中断线程的是调用Thread#interrupt() 。 从第17.2.3节开始 ,JLS在这个问题上相对清楚:

17.2.3中断

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

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

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

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

按照惯例,任何通过抛出InterruptedException退出的方法都会在执行此操作时清除中断状态。 但是,通过另一个调用interrupt线程,总是可以立即再次设置中断状态。

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

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


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

您在处理InterruptedException看到的许多注释和“警告”并不意味着它们可以完全自发地抛出,它们旨在鼓励设计良好的对象,这些对象可以在尚未知的上下文中使用,其中interrupt()假设可以工作(所以,你确实想要假设如果你创建的可重用对象在未来的情况下会很强大,你可以自发地抛出它们 – 也就是说,你永远不能保证你的代码不会在某一天被使用有人希望中断工作)。

对于快速的一次性项目,你不必担心这些exception的特殊处理,只要你知道你没有调用interrupt()并且没有调用可以调用interrupt()东西,但是从长远来看,请注意这一点,特别是如果你最终在其他环境中重用该代码。