为什么 InterruptedException 是一个受检异常?

14
在Java中处理线程时,处理InterruptedException似乎是一个特别棘手的问题。我欣赏它在我的线程被终止时抛出,因此为我提供了清理的机会。但奇怪的是,它不是一个未经检查的异常。
这创建了以下问题:
a)如果我想在我的多线程应用程序中使用现有的框架,则必须将其转换为框架接口接受的异常。 因此,该框架通常会错误地解释它,而不是像应该那样进行清理或传播。
b)除非针对堆栈中的每个调用严格声明InterruptedException(而通常由于a)而不是这样),否则很难进行干净的关闭。
如果InterruptedException改为未经检查,则似乎更有可能被正确使用,并导致线程和应用程序的干净关闭。 那为什么不是呢?

我想决定将此异常设置为已检查与未检查是基于在实现多线程解决方案时的可见性。这是一种“嘿,你应该真正关注这个并把它做对”的事情。在编译时强制执行至少迫使实现者考虑被中断的问题。如果将其设置为未检查,则会将此问题的可见性移动到视野之下。 - Michael Krause
1
投票关闭此问题,因为除了指定的人之外,我们只能做出有根据的猜测。 - Hannes
1
(a) 这是你的框架存在问题,而不是 InterruptedException 本身的问题。 (b) RuntimeException 表示编程错误;InterruptedException 不是编程错误的结果。 - Sergey Kalinichenko
1
@eckes:我不明白一个异常是否难以处理与它是否应该被检查有什么关系。 - Andy
因为你可能会意外捕获它并处理错误 - 或者在很少发生的IE情况下,你可能会忘记在重试循环中处理它。 - eckes
显示剩余2条评论
1个回答

9
中断应该是协作的。我认为设计者想要避免你中断一个线程时可能会使线程崩溃的情况,即线程没有代码来处理这种情况。他们的意图似乎是让可运行代码明确地决定如何处理中断。很多框架或语言代码似乎都是关于决定谁应该负责某个事情,并试图使正确的用法显而易见,以最小化用户遭受的损失。这是其中之一需要判断的问题。
通过检查InterruptedException,最坏的情况是捕获异常,但以一种不是非常有用的方式。实际上,最糟糕的情况是中断标志未恢复,导致线程中的任何后续代码都不知道发生了中断。如果InterruptedException未被检查(或者如果您将其包装在RuntimeException中,如评论中链接的文章所示),则可能无法处理该异常并继续终止线程,如果线程没有处于停止位置,这可能是非常糟糕的。
玩具示例和简单代码与未经检查的InterruptedException更好地配合使用;没有人会费心去捕获异常,它只会起作用。然而,在真正的代码中执行实质性工作时,这可能被认为是有害的。
将异常设为已检查是为了确保开发人员知道可能会抛出异常,以便开发人员避免在线程正在进行的工作中抛出异常的情况,从而可能使工作处于部分完成的坏状态。

2
我同意中断应该是协作的。但是,如果异常未经检查,则提供“尽力而为”的妥协。你可以尽力合作,也可以忽略它,但无论哪种方式,你都将被关闭,而不是可能在不稳定的状态下继续运行。 - Andy
2
@Andy:这方面确实有好处。无论如何,我不是受检异常的粉丝。 - Nathan Hughes

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