我在爱好项目中使用java.util.concurrent.Semaphore
。它用在我写的连接池类中。我可以毫不费力地使用它,除了这个方法:
public void acquire(int permits) throws InterruptedException
迫使我处理InterruptedException
。现在,我不确定什么“打断”一个线程甚至意味着我在我的代码中从不这样做(好吧,不是明确地说)。这是否意味着我可以忽略该异常?我该怎么处理呢?
答案 0 :(得分:28)
是的,您需要担心InterruptedException
,就像您需要担心任何其他必须抛出或处理的已检查异常一样。
大部分时间InterruptedException
表示停止请求,很可能是由于运行代码的线程为interrupted这一事实。
在您等待获取连接的连接池的特定情况下,我会说这是一个取消问题,您需要中止采集,清理并恢复中断的标志(见下文)。
例如,如果您在Runnable
内使用某种Callable
/ Executor
,那么您需要正确处理InterruptedException:
executor.execute(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch ( InterruptedException e) {
continue; //blah
}
pingRemoteServer();
}
}
});
这意味着您的任务永远不会遵循执行程序使用的中断机制,也不允许正确的取消/关闭。
相反,正确的习惯用法是恢复中断状态然后停止执行:
executor.execute(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch ( InterruptedException e) {
Thread.currentThread().interrupt(); // restore interrupted status
break;
}
pingRemoteServer();
}
}
});
有用资源:
答案 1 :(得分:6)
不。只有在您自己中断线程时才会生成InterruptedException
。如果您自己不使用Thread.interrupt()
,那么我会将其重新抛出为某种“意外异常”或将其记录为错误并继续前进。例如,在我的代码中,当我被迫抓住InterruptedException
并且我从不打电话给interrupt()
时,我做的相当于
catch (InterruptedException exception) {
throw new RuntimeException("Unexpected interrupt", exception);
}
如果是意料之外的话。有很多地方我故意打断我的线程,在那些情况下我以明确的方式处理InterruptedException
。通常是通过退出我所处的循环,清理,然后停止线程。
答案 2 :(得分:1)
可以通过调用Thread.interrupt()来中断线程。它用于优雅地发信号通知它应该做其他事情。通常它会导致阻塞操作(例如Thread.sleep())提前返回并抛出InterruptedException。如果线程被中断,则会在其上设置一个标志。可以通过Thread.isInterrupted()调用查询此标志。
如果你不使用线程中断并仍然得到这个异常,你可以退出你的线程(并且最好记录异常)。
通常,它取决于您的多线程应用程序的功能。
答案 3 :(得分:1)
如果您不知道如何在方法中处理它,我建议您在方法中使用throws InterruptedException(以及调用者等)声明它
如果它是你永远不会发生的事情,我会抓住它并将其包装在AssertionError中。
答案 4 :(得分:0)
在执行了线程所需的任何清理后,您应该退出run()方法 HTH