如果我自己不打断任何内容,我是否必须担心InterruptedExceptions?

34 java concurrency exception

java.util.concurrent.Semaphore在一个爱好项目中使用.它用在我写的连接池类中.我可以毫不费力地使用它,除了这个方法:

public void acquire(int permits) throws InterruptedException
Run Code Online (Sandbox Code Playgroud)

这迫使我处理InterruptedException.现在,我不确定什么"打断"一个线程甚至意味着我在我的代码中从不这样做(好吧,不是明确地说).这是否意味着我可以忽略该异常?我应该怎么处理?

Rob*_*anu 30

是的,您需要担心InterruptedException,就像您需要担心任何其他必须抛出或处理的已检查异常一样.

大多数情况下,InterruptedException发出停止请求的信号,很可能是由于运行代码的线程被中断的事实.

在您等待获取连接的连接池的特定情况下,我会说这是一个取消问题,您需要中止采集,清理并恢复中断的标志(见下文).


例如,如果您正在使用某种Runnable/ Callable在内部运行,Executor那么您需要正确处理InterruptedException:

executor.execute(new Runnable() {

    public void run() {
         while (true) {
              try {
                 Thread.sleep(1000);
              } catch ( InterruptedException e) {
                  continue; //blah
              }
              pingRemoteServer();
         }
    }
});
Run Code Online (Sandbox Code Playgroud)

这意味着您的任务永远不会遵循执行程序使用的中断机制,也不允许正确的取消/关闭.

相反,正确的习惯用法是恢复中断状态然后停止执行:

executor.execute(new Runnable() {

    public void run() {
         while (true) {
              try {
                 Thread.sleep(1000);
              } catch ( InterruptedException e) {
                  Thread.currentThread().interrupt(); // restore interrupted status
                  break;
              }
              pingRemoteServer();
         }
    }
});
Run Code Online (Sandbox Code Playgroud)

有用的资源:

  • 绝对.有关详细信息,请参阅Java专家新闻通讯http://www.javaspecialists.co.za/archive/Issue056.html (3认同)

Joh*_*ica 6

不.InterruptedException仅在您自己中断线程时生成.如果你不自己使用Thread.interrupt()那么我会把它作为某种"意外的异常"重新抛出或将其记录为错误并继续前进.例如在我的代码中,当我被迫抓住InterruptedException并且我从不打电话给interrupt()自己时,我做的相当于

catch (InterruptedException exception) {
    throw new RuntimeException("Unexpected interrupt", exception);
}
Run Code Online (Sandbox Code Playgroud)

如果这是意料之外的话.有很多地方我故意打断我的线程,在那些情况下我InterruptedException以明确的方式处理s.通常是通过退出我所处的循环,清理,然后停止线程.


aka*_*okd 2

线程可以通过调用Thread.interrupt()来中断。它用于优雅地向线程发出信号,指示它应该执行其他操作。通常它会导致阻塞操作(例如Thread.sleep())提前返回并抛出InterruptedException。如果线程被中断,则会在其上设置一个标志。可以通过 Thread.isInterrupted() 调用查询该标志。

如果您不使用线程中断并且仍然收到此异常,您可以退出线程(最好记录异常)。

一般来说,这取决于您的多线程应用程序的用途。