以下处理InterruptedException个问题的方法有什么不同?最好的方法是什么?

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

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

编辑:我还想知道这两个应用在哪些场景中.

推荐答案

以下处理中断异常的方法有什么区别?最好的方法是什么?

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

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

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

Does it make sense for the method you are implementing to throw an 100?换句话说,当调用your方法时,InterruptedException是一个合理的结果吗?

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

    Example:您的方法等待来自网络的值完成计算并返回结果.如果阻塞网络调用抛出InterruptedException,则您的方法无法以正常方式完成计算.你让InterruptedException人传播.

    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. 即使your方法能够在InterruptedException的情况下产生一个合理的返回值,线程被中断的事实可能仍然很重要.特别是,调用方法的代码可能对方法执行期间是否发生中断感兴趣.因此,您应该通过设置中断标志Thread.currentThread().interrupt()来记录中断发生的事实

    Example:用户要求打印两个值的总和.如果无法计算总和,则打印"Failed to compute sum"是可以接受的(这比让程序因InterruptedException而导致堆栈跟踪崩溃要好得多).换句话说,用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)不是一个好主意.这对打电话的人不太礼貌.您可以发明一个新的运行时异常,但根本原因(有人希望线程停止执行)可能会丢失.

Other examples:

Implementing 101:正如你可能已经发现的那样,Runnable.run的签名不允许重播InterruptedExceptions.you签署了实施Runnable的协议,这意味着you签署了处理可能的InterruptedExceptions的协议.或者 Select 一个不同的界面,比如Callable,或者遵循上面的第二种方法.

 

Calling 100:你正在try 读取一个文件,规范说你应该在间隔1秒的时间内try 10次.你打Thread.sleep(1000).所以,你需要处理InterruptedException个问题.对于tryToReadFile这样的方法来说,最好说"If I'm interrupted, I can't complete my action of trying to read the file".换言之,这个方法抛出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中Stream(java.util.stream)和linkedList数据 struct 之间是什么关系?

PostgreSQL货币兑换率查询

如何让HikariCP指标在NewRelic中正确显示?

将状态栏和导航栏设置为白色,带有深色文本

在URL类图中表示Java swing类

Java 22模式匹配不适用于记录模式匹配.给出汇编问题

有关手动创建的包的问题

Spring data JPA/Hibernate根据id获取一个列值

为什么在maven中,getLast方法不适用于List?

如何让JavaFx应用程序识别依赖项?

将Spring Boot 3.2.0升级到3.2.1后查询执行错误

在添加AdMob时无法为Google Play构建应用程序包:JVM垃圾收集器崩溃和JVM内存耗尽

由于在生成器模式中使用泛型,lambda表达式中的返回类型错误

当构造函数创建一个新实例时,Java为什么需要&new";

在Spring Boot应用程序中,server.port=0的默认端口范围是多少?

在使用具有不同成本的谓词调用allMatch之前对Java流进行排序会带来什么好处吗?

除0错误/抱歉我的句子是PT

使用@ExceptionHandler的GlobalExceptionHandler还是来自服务器的REST应答的ResponseEntity?

使用同步方法中的新线程调用同步方法

可以';不要在Intellij IDEA中使用最新的Java版本(JDK 21)