在执行 KafkaTemplate.send 时在 catch 块中捕获 InterruptedException 时,我是否应该重新抛出中断?

Should i rethrow an interrupt when catching an InterruptedException in the catch block when doing a KafkaTemplate.send?

使用配置为 bean 的 KafkaTemplate 将记录发送到主题:

@Bean
public KafkaTemplate<Object, Object> kafkaTemplate() {
    return new KafkaTemplate<>(producerFactory());
}

,一个会做:

@Autowired
private KafkaTemplate<Object, Object> kafkaTemplate;
...
SendResult<Object, Object> sendResult = kafkaTemplate.send(topic, object).get();

并且会通过将上面的内容包装在 try/catch 块中来捕获 InterruptedException & ExecutionException

try {
  SendResult<Object, Object> sendResult = kafkaTemplate.send(topic, object).get();
  if (sendResult.getRecordMetadata() != null && sendResult.getRecordMetadata().hasOffset()) {
     //some code
  } else {
     //some code
  }
} catch (InterruptedException | ExecutionException e) {     
  logger.error("An error has occurred: ", e);
}

最近,我了解到发生中断异常时的最佳做法是像这样在 catch 块中重新抛出它:

} catch (InterruptedException | ExecutionException e) {     
  logger.error("An error has occurred: ", e);
  Thread.currentThread().interrupt();
}

(1) 在 KafkaTemplate 上下文中是否推荐这样做?我倾向于认为不会,因为我看到的所有示例都没有重新抛出中断。
(2) 如果是,好处是什么
(3) 中断不重抛有没有缺点?

这是基本的中断处理,与Kafka无关。

Thread.currentThread().interrupt();

是的,这是最佳做法。

你不是"rethrowing"那里的中断,你正在设置中断位,这样,如果在线程上执行下游可中断操作,它也会被中断。

如果不设置中断位会有很大的缺点。当一个线程被中断时,通常应用程序希望线程退出它正在做的事情。

考虑:

public void method2() {

    ...
    try {
        Thread.sleep(1000);
    }
    catch (InterruptedException e) {
        // ignore
    }

}

public void method1() throws InterruptedException {

    ...
    method2();
    System.out.println("method2 returned ok");
    Thread.sleep(Long.MAX_VALUE);

}

线程将挂起并且永远不会退出,因为您 "ate" 中断。

但是,您应该在多捕获中这样做:

} catch (InterruptedException | ExecutionException e) {     
  logger.error("An error has occurred: ", e);
  Thread.currentThread().interrupt();
}

这将设置两个异常的中断位,而不仅仅是 InterruptedException