什么行为会导致“中断异常”?

34

我对Java中的线程处理相对较新,但我注意到每次使用Thread.sleep()方法时都需要捕获InterruptedException异常。

是什么行为导致了这种情况?在简单的应用程序中,如果我有一个监视器线程,我是否可以忽略这个异常?


类似于这个问题:https://dev59.com/cHTYa4cB1Zd3GeqPrCP1#17495107 - Eric des Courtis
7个回答

30

当线程被调用interrupt()时,就会发生这种情况。 Brian Goetz的这篇文章解释了中断机制以及如何处理InterruptedException:

"最常见的对InterruptedException的响应是将其吞掉——捕获它并不做任何事情(或者记录日志,这并不比什么好)——正如我们后面在清单4中所看到的。不幸的是,这种方法丢弃了有关中断已发生的重要信息,这可能会损害应用程序取消活动或及时关闭的能力。"

"如果你捕获InterruptedException但无法重新抛出它,你应该保留中断发生的证据[...]。通过调用interrupt()来“重新中断”当前线程可以完成此任务。"


2
谢谢你提出这个观点。管理InterruptedException很麻烦,但是很重要。 - Spencer Kormos
3
很好的参考资料,但并没有完全回答楼主的真正问题。重新解释一下,就是“为什么线程会被中断?”,而给出的答案是“因为其他某个线程决定这样做”。我猜测楼主的真正意图是“在更大的Java生态系统中是否有什么原因导致这种情况发生?”例如System.exit?从main()方法返回?太阳黑子? :-) - Charles Roth

8

正如其他人所说,这是由于其他线程在休眠的Thread对象上调用了interrupt()引起的。

这意味着另一个线程已决定取消休眠的线程。try/catch块存在的原因是为了优雅地处理线程的取消,并安全地清理任何资源或正确关闭它正在进行的任何操作。

如果您实际上不需要执行任何操作,则仍然需要一个空的catch块。但这就是Java......


7

《Java并发编程实战》中的一些建议:

  • 传播异常(在特定任务清理后),使您的方法也成为可中断的阻塞方法;或者
  • 恢复中断状态,以便调用栈上更高层次的代码可以处理它。
  • 只有实现线程中断策略的代码才能吞噬中断请求。通用任务和库代码不应该吞噬中断请求。

3

主要情况是当有人在您的线程上调用Thread.interrupt()时。

如果发生在您不希望发生的情况下,抛出RuntimeException可能更安全,但对于非常简单的情况,您可能可以忽略它。


3

Java文档中得知:

InterruptedException类

当一个线程在等待、睡眠或者其他方式长时间暂停时,另一个线程使用Thread类的interrupt方法来打断它,则抛出该异常。

希望这回答了您的问题。


-1

如果其他线程在该线程处于睡眠状态时调用thread.interupt(),则会出现异常。是的,你可以在sleep()周围放置try..catch并忽略它 ;)


25
降级是因为你绝对不能忽略任何异常,这会导致未记录的行为和错误。要么记录它,要么将其向上抛出。 - Spencer Kormos
吞咽InterruptedException会损害应用程序取消活动或及时关闭的能力。更多信息请参见http://www.ibm.com/developerworks/library/j-jtp05236/。 - Kumar Abhinav
3
虽然大多数情况下不能忽略异常,但有些例外情况是可以被忽略的。比如,当线程的引用仅存在于范围内时,就不存在意外行为的可能性。我们是软件工程师,应该自己思考。如果连为什么要处理异常都不问自己,那你可能是个糟糕的工程师。 - Eldar Kersebaum

-1

InterruptedException 是一种检查异常,所以不幸的是你不能忽略它。在大多数简单的情况下,你不必在 catch 子句中做任何事情,因为你确定它不会发生。

来自 API

当一个线程正在等待、休眠或以其他方式长时间暂停并且另一个线程使用 Thread 类中的 interrupt 方法中断它时抛出。


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