我对Java中的线程处理相对较新,但我注意到每次使用Thread.sleep()方法时都需要捕获InterruptedException异常。
是什么行为导致了这种情况?在简单的应用程序中,如果我有一个监视器线程,我是否可以忽略这个异常?
我对Java中的线程处理相对较新,但我注意到每次使用Thread.sleep()方法时都需要捕获InterruptedException异常。
是什么行为导致了这种情况?在简单的应用程序中,如果我有一个监视器线程,我是否可以忽略这个异常?
当线程被调用interrupt()时,就会发生这种情况。 Brian Goetz的这篇文章解释了中断机制以及如何处理InterruptedException:
"最常见的对InterruptedException的响应是将其吞掉——捕获它并不做任何事情(或者记录日志,这并不比什么好)——正如我们后面在清单4中所看到的。不幸的是,这种方法丢弃了有关中断已发生的重要信息,这可能会损害应用程序取消活动或及时关闭的能力。"
"如果你捕获InterruptedException但无法重新抛出它,你应该保留中断发生的证据[...]。通过调用interrupt()来“重新中断”当前线程可以完成此任务。"
正如其他人所说,这是由于其他线程在休眠的Thread
对象上调用了interrupt()
引起的。
这意味着另一个线程已决定取消休眠的线程。try/catch块存在的原因是为了优雅地处理线程的取消,并安全地清理任何资源或正确关闭它正在进行的任何操作。
如果您实际上不需要执行任何操作,则仍然需要一个空的catch块。但这就是Java......
《Java并发编程实战》中的一些建议:
- 传播异常(在特定任务清理后),使您的方法也成为可中断的阻塞方法;或者
- 恢复中断状态,以便调用栈上更高层次的代码可以处理它。
- 只有实现线程中断策略的代码才能吞噬中断请求。通用任务和库代码不应该吞噬中断请求。
主要情况是当有人在您的线程上调用Thread.interrupt()时。
如果发生在您不希望发生的情况下,抛出RuntimeException可能更安全,但对于非常简单的情况,您可能可以忽略它。
从Java文档中得知:
InterruptedException类
当一个线程在等待、睡眠或者其他方式长时间暂停时,另一个线程使用Thread类的interrupt方法来打断它,则抛出该异常。
希望这回答了您的问题。
如果其他线程在该线程处于睡眠状态时调用thread.interupt(),则会出现异常。是的,你可以在sleep()周围放置try..catch并忽略它 ;)
InterruptedException 是一种检查异常,所以不幸的是你不能忽略它。在大多数简单的情况下,你不必在 catch 子句中做任何事情,因为你确定它不会发生。
来自 API
当一个线程正在等待、休眠或以其他方式长时间暂停并且另一个线程使用 Thread 类中的 interrupt 方法中断它时抛出。