java - 在 Java 中处理 InterruptedException

标签 java multithreading exception-handling interrupted-exception

以下处理InterruptedException的方式有什么区别?最好的方法是什么?

try{
 //...
} catch(InterruptedException e) { 
   Thread.currentThread().interrupt(); 
}

try{
 //...
} catch(InterruptedException e) {
   throw new RuntimeException(e);
}

编辑:我也想知道这两个在哪些场景中使用。

最佳答案

What is the difference between the following ways of handling InterruptedException? What is the best way to do it?

您可能会问这个问题,因为您调用了一个抛出 InterruptedException 的方法。

首先,您应该看到 throws InterruptedException 是什么:方法签名的一部分以及调用您正在调用的方法的可能结果。因此,首先要接受 InterruptedException 是方法调用的完全有效结果这一事实。

现在,如果你调用的方法抛出了这样的异常,你的方法应该怎么做?您可以通过思考以下问题来找出答案:

实现的方法抛出InterruptedException有意义吗?换句话说,是InterruptedException调用你的方法时的合理结果?

  • 如果 yes,则 throws InterruptedException 应该是 您的 方法签名的一部分,并且您应该让异常传播(即根本不要捕获它)。

    Example: Your method waits for a value from the network to finish the computation and return a result. If the blocking network call throws an InterruptedException your method can not finish computation in a normal way. You let the InterruptedException propagate.

    int computeSum(Server server) throws InterruptedException {
        // Any InterruptedException thrown below is propagated
        int a = server.getValueA();
        int b = server.getValueB();
        return a + b;
    }
    
  • 如果 no,那么你不应该用 throws InterruptedException 声明你的方法,你应该(必须!)捕获异常。在这种情况下,有两点需要牢记:

    1. 有人打断了你的话题。有人可能急于取消操作,优雅地终止程序,或其他任何事情。你应该对那个人有礼貌,然后毫不犹豫地从你的方法中返回。

    2. 即使 您的 方法可以设法在 InterruptedException 的情况下产生合理的返回值,但线程已被中断的事实可能仍然很重要.特别是,调用您的方法的代码可能对您的方法执行期间是否发生中断感兴趣。因此,您应该通过设置中断标志来记录发生中断的事实:Thread.currentThread().interrupt()

    Example: The user has asked to print a sum of two values. Printing "Failed to compute sum" is acceptable if the sum can't be computed (and much better than letting the program crash with a stack trace due to an InterruptedException). In other words, it does not make sense to declare this method with throws InterruptedException.

    void printSum(Server server) {
         try {
             int sum = computeSum(server);
             System.out.println("Sum: " + sum);
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();  // set interrupt flag
             System.out.println("Failed to compute sum");
         }
    }
    

现在应该清楚了,仅仅执行 throw new RuntimeException(e) 是个坏主意。这对来电者不太礼貌。您可以发明一个新的运行时异常,但根本原因(有人希望线程停止执行)可能会丢失。

其他示例:

Implementing Runnable: As you may have discovered, the signature of Runnable.run does not allow for rethrowing InterruptedExceptions. Well, you signed up on implementing Runnable, which means that you signed up to deal with possible InterruptedExceptions. Either choose a different interface, such as Callable, or follow the second approach above.

 

Calling Thread.sleep: You're attempting to read a file and the spec says you should try 10 times with 1 second in between. You call Thread.sleep(1000). So, you need to deal with InterruptedException. For a method such as tryToReadFile it makes perfect sense to say, "If I'm interrupted, I can't complete my action of trying to read the file". In other words, it makes perfect sense for the method to throw InterruptedExceptions.

String tryToReadFile(File f) throws InterruptedException {
    for (int i = 0; i < 10; i++) {
        if (f.exists())
            return readFile(f);
        Thread.sleep(1000);
    }
    return null;
}

本帖已改写为文章 here .

关于java - 在 Java 中处理 InterruptedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3976344/

相关文章:

java - 使用 Fmeasure 进行引导的评分模式

java - 为什么 "catch" block 一定需要异常类型?

php - 为什么 Symfony2 不捕获异常

python - 从 python __exit__ block 中重新分配异常

java - 是否可以在 intellij 中同时将 int 视为十进制和十六进制?

java - JSP 页面显示 bean 为空值

java - SpringBoot应用程序中的主类

.net - 正确的方法来使Winforms UI阻塞对话框,直到出现一些非用户驱动的事件条件?

java - 如果线程在同步块(synchronized block)中抛出异常会发生什么

multithreading - 如何在GWT服务器端进行编码?