关于Java的InterruptedException,有一些有趣的问题和答案,例如The Cause of InterruptedException和Handling InterruptedException in Java。但是,它们都没有告诉我InterruptedException的可能来源。
如SIGTERM,SIGQUIT,SIGINT等操作系统信号怎么样?在命令行上按CTRL-C会产生InterruptedException吗?还有什么?
答案 0 :(得分:21)
您列出的所有内容都不会产生InterruptedException
。
唯一可以中断线程的是对Thread#interrupt()
的调用。 JLS在此问题上相对明确,来自section 17.2.3:
17.2.3中断
调用
Thread.interrupt
时会发生中断操作 定义为依次调用它的方法,例如ThreadGroup.interrupt
。
有关更多信息,请参阅the official tutorial on interrupts。具体做法是:
线程通过在
interrupt
对象上调用Thread
来发送中断,以便线程被中断。为使中断机制正常工作,被中断的线程必须支持自己的中断。...
使用称为中断状态的内部标志实现中断机制。调用
Thread.interrupt
设置此标志。当线程通过调用静态方法Thread.interrupted
检查中断时,中断状态被清除。非静态isInterrupted
方法(由一个线程用于查询另一个线程的中断状态)不会更改中断状态标志。按照惯例,任何通过抛出
InterruptedException
退出的方法都会在执行此操作时清除中断状态。但是,通过调用interrupt
的另一个线程,可以立即再次设置中断状态。
这意味着它只能通过调用interrupt()
来设置显式标志,而不是由其他未知的外部事件触发。引用它的各种方法中的异常描述进一步暗示了这一点,for example(强调我的):
InterruptedException
- 如果有任何线程中断当前线程。抛出此异常时,将清除当前线程的中断状态。
中断系统的目的通常是提供一个通用的,定义良好的框架,允许线程在其他线程中中断任务(可能是耗时的)。虽然您可以在自己的应用程序中使用显式逻辑实现类似的功能,但是使用这种定义良好的机制允许独立的类(例如JDK,其他第三方代码,您自己的代码中的其他独立类)以一致的方式提供此功能。
许多笔记和警告"你看到处理InterruptedException
并不意味着它们可以被完全自发地抛出,它们意味着鼓励精心设计的对象,这些对象可以在尚未知晓的情境中使用,其中{{1}假设可以工作(实际上,你做想要假设如果你创造的可重用对象在未来的情况下会很强大,你可以自发地抛出它们 - 即你永远不会保证你的代码不会被那些期望中断工作的人使用。
对于快速的一次性项目,只要您确定自己没有打电话{{1>,那么 并且没有调用可以调用interrupt()
的东西,但是从长远来看,请注意它的含义,特别是如果你最终在其他上下文中重用该代码。