在执行 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
。
使用配置为 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
。