- 为什么睡眠线程需要 try catch 来捕获中断异常?
- 为什么 sleep 甚至会发出 Interrupted Exception 错误?这是我一直在通过谷歌搜索的java编程中我真正想找出的两个问题,但我仍然没有找到明确的解释来解释为什么会发生这两件事。
6 回答
InterruptedException
当线程被阻塞/等待并且它被另一个线程(通过 )中断时抛出一个Thread.interrupt
。将其视为立即终止的请求,不会遭受Thread.stop()
.
这样,即使您指示一个线程休眠几年,您也可以中断该线程。
推荐的做法InterruptedException
是在抛出a 时中止您正在处理的任何内容。
- 因为如果你中断一个线程,它就不能完成它的正常执行,你需要抓住它才能准备好做某事。
- 因为线程等待与中断线程不同,线程等待可以恢复,但中断线程已经完成执行。
当您要求线程休眠时,该线程的预期行为是休眠这么长时间。所以如果sleep被打断了,就会抛出InterruptedException,表示无法完成任务。如果它被中断,您可能需要注意应该做什么。
这里有一个如何抛出中断异常的干净示例:http ://www.javamex.com/tutorials/threads/thread_interruption.shtml
sleep()
并yield()
在这里讨论:http: //www.coderanch.com/t/508657/threads/java/Sleep-Yield-state
这是因为sleep()
可能会永久/很长时间阻塞,因此您需要一种能够取消此行为的方法。因为当您中断操作时它不是“正常”完成,您可能需要执行一些特定的补偿或补救操作,例如,发送您从未收到通知的警报,清理资源等。
有一个非常好的开发人员关于该主题的作品文章。
睡眠和中断在语义上不相关。只是Java设计者认为当你想让你的线程休眠时,这是一个提醒你中断的好机会。这就像杜克说“看起来你正在尝试睡觉,你是否也想通过确保它正确响应中断事件来使你的线程成为一个好公民,当需要一种方法让它突然终止时在您项目的后期出现?”
所以经常会看到这样的代码:
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
//Don't worry about it.
}
有时人们说这被认为是不好的做法。但是如果你不打算在你的程序中使用中断工具,那么这些异常将永远不会被抛出,所以你必须问自己是否做额外的工作来处理这些异常,以防你决定添加一段时间后程序的可中断性功能是有道理的。这是 Java 设计者坚持认为每个线程都应该做的事情之一——你可以interrupt()
做到,它会快速而干净地中止它正在做的事情。我认为在很多情况下这是不必要的,但是人们会查看您的代码,看到这个并且仍然说“哎呀,不好的做法!”
Java 官方教程解释了中断。基本上,如果你有一个线程t
在做一些处理,然后用户想取消它,你会从另一个线程调用t.interrupt()
. 在 thread 上运行的代码中t
,只要它sleep()
是 s 或wait()
s 等,InterruptedException
就会抛出 an 。如果它不做任何这些,那么它也可以(应该)查明它是否Thread.interrupted()
不时被中断使用。在所有这些发现中断的方法中,它应该放弃它正在做的事情并尽快清理。(也就是说:如果它这样做了,那么这种行为可能对你或某人有用——这就是中断的概念。)
因此,Java 将此作为sleep(..)
方法的检查异常,以迫使您考虑使用此工具。另一部分理由是,如果 sleep(..)
被打断,那么它会早早醒来,这是一个例外事件。(但请记住,有那个“如果”。)
重要的是中断不会无缘无故地发生。如果您编写代码使它们发生,或者如果其他人启动您的线程并需要取消他们的活动,它们就会发生。所以这就是Thread.sleep(..)
抛出一个InterruptedException
. 你做。如果你不这样做,那么你仍然需要抓住它。
编辑。顺便说一句,这样做会更好:
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
throw new UnsupportedOperationException("Interrupts not supported.", ie);
}
因此,如果您或其他人稍后试图错误地中断该线程,那么当他们去测试它时,他们会被提醒该功能未实现。(UnsupportedOperationException
是 的子类RuntimeException
,因此未选中。)