为什么要捕获InterruptedException并调用Thread.currentThread.interrupt()?

12

在《Effective Java》(第275页)中,有这段代码:

...
for (int i = 0; i < concurrency; i++) {
  executor.execute(new Runnable() {
    public void run() {
    ready.countDown();
    try {
      start.await();
      action.run();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      done.countDown();
    }
  }
}
...

为什么要捕获中断异常再重新抛出它?不直接让它飞行不行吗?

3个回答

16
简单来说,InterruptedException是一个已检查(checked)的异常,它没有在Runnable.run方法(或Executable.execute()方法)的签名中。因此你必须捕获它。一旦你捕获了它,调用Thread.interrupt()来设置中断标志是推荐的做法...除非你真的想忽略这个中断。

1
假设您希望线程实际上被中断。您也可以捕获并吞咽异常,这将抑制线程中断。 - Francis Upton IV
你的意思是Runnable接口中没有这个方法签名。我会使用Callable接口代替。另外,调用Thread.currentThread().interrupt()不会抛出那个异常吗?那抛出它有什么意义呢? - ripper234
我相信你的意思是 InterruptedException 是一个受检异常,并不在 Runnable.run() 的签名中(而不是 Executor.execute)。 - Tom

0
有时候你不能忽略异常,必须捕获它。主要出现在你重写一个方法,并且根据其签名不能抛出InterruptedException异常的情况下。例如,在 Runnable.run() 方法中通常会使用这种方法。

0

执行器可以在任务被取消时中断它们,但在任务之间清除中断标志,以避免一个被取消的任务中断一个不相关的任务。

因此,在这里中断当前线程如果实际上有任何作用将是危险的。

解决这个问题的一个简单方法是使用Callable或忽略中断。

另外,最好捕获和记录try/catch块中抛出的任何错误或异常,否则异常/错误将被丢弃,您的程序可能会失败,但您不知道它失败了或为什么失败。


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