我正在使用 Thread.sleep(10000); 因此我需要处理 InterruptedException。我可以调用 Thread.currentThread.interrupt () 然后将异常抛出给调用类,或者我可以直接将它抛出给调用类或者有没有更好的方法来处理它?
4 回答
如果您有一个循环和轮询的专用线程,那么在我看来,这就像程序结束时需要终止的东西;除非它是一个守护线程(这意味着你很高兴它消失而没有机会清理或关闭资源)它需要能够处理中断。使用 WatchService 似乎是个好主意,但是使用 WatchService 的代码仍然必须知道如何处理中断。
如果您正在编写一个休眠的 Runnable 或 Callable,您可以使用 InterruptedException 退出您正在执行的任何循环,或者您可以捕获异常并恢复中断标志,以便下一次检查中断标志(使用Thread.currentThread().isInterrupted()
)可以看到线程已被中断:
while(!Thread.currentThread().isInterrupted()){
//do something
try{
Thread.sleep(5000);
} catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
或者,您可以使用 InterruptedException 退出循环:
try {
while (!Thread.currentThread().isInterrupted()) {
// do something
Thread.sleep(5000);
}
} catch (InterruptedException e) {
// flag value is not used here
Thread.currentThread().interrupt();
}
如果您正在开发一个希望嵌套在其他对象中的对象,则抛出异常并将其添加到方法签名中。例如,查看 java.util.concurrent 包中的类(如BlockingQueue )的 API 文档,了解 put 和 offer 等方法如何抛出 InterruptedException。当为并发创建的对象组合在一起时,它们需要合作(并确保它们不会丢失对中断状态的跟踪),以确保它们可以以响应方式清理和终止。
在大多数普通代码中,您不应该使用sleep
. 通常有更好的方法来做你想做的事。
我可以调用 Thread.currentThread.interrupt()
如果您想正常继续,但无需等待,这很有用。
然后将异常抛出到调用类
或者我会抛出一个异常,你可以用你选择的一个来包装异常。
或者我可以直接把它扔给调用类
在这种情况下,您最好不要抓住。
或者有没有更好的方法来处理它?
这取决于您为什么希望线程被中断。如果我不希望有中断,我会用AssertionError
一般来说,如果可以重新抛出,或者如果不能重新抛出,则设置中断标志。
关于这方面的一篇好文章是http://www.ibm.com/developerworks/library/j-jtp05236/
这是最相关的摘录是:
当阻塞方法检测到中断并抛出 InterruptedException 时,它会清除中断状态。如果您捕获了 InterruptedException 但无法重新抛出它,您应该保留中断发生的证据,以便调用堆栈上较高的代码可以了解中断并在需要时对其进行响应。
我正在使用 Thread.sleep(10000); 因此我需要处理 InterruptedException。
不必要。处理有聪明的方法InterruptedException
,也有愚蠢的方法。如果您的线程实际上永远不会被中断,那么您选择哪种方式真的很重要吗?
当然,如果您认为您的代码可能会被重用,或者如果您认为其他程序员会阅读它,那么您可能想要采用聪明的方式。如果你想养成良好的编码习惯,你可能想采用聪明的方式(那里有很多例子,只是等着用谷歌搜索找到)。
但有时我们只想写一个快速的 hack,我们将使用一次然后扔掉......