Either re-interrupt this method or rethrow the “InterruptedException”.
请重新中断此方法或重新引发“InterruptedException”。
文章目录
- 问题描述
- 问题解析
- sonar检测提示规则
- 解决方案
问题描述
public void run () {
try {
while (true) {
// do stuff
}
}catch (InterruptedException e) {
LOGGER.log(Level.WARN, "Interrupted!", e);
}
}
问题解析
sonar检测提示规则
InterruptedExceptions should never be ignored in the code, and simply logging the exception counts in this case as “ignoring”. The throwing of the InterruptedException clears the interrupted state of the Thread, so if the exception is not handled properly the fact that the thread was interrupted will be lost. Instead, InterruptedExceptions should either be rethrown - immediately or after cleaning up the method’s state - or the thread should be re-interrupted by calling Thread.interrupt() even if this is supposed to be a single-threaded application. Any other course of action risks delaying thread shutdown and loses the information that the thread was interrupted - probably without finishing its task.
Similarly, the ThreadDeath exception should also be propagated. According to its JavaDoc代码中决不应忽略InterruptedExceptions,在这种情况下,只需将异常计数记录为“忽略”即可。抛出InterruptedException将清除线程的中断状态,因此如果异常处理不当,线程被中断的事实将丢失。相反,InterruptedExceptions应该立即或在清理方法状态后重新抛出,或者通过调用Thread.interrupt()来重新中断线程,即使这是一个单线程应用程序。任何其他操作过程都有延迟线程关闭的风险,并丢失线程被中断的信息——可能没有完成任务。
同样,也应传播ThreadDeath异常。
解决方案
- 重新标记一下线程中断状态
Thread.currentThread().interrupt();
- 抛出异常
throw InterruptedException
public void run () {
try {
while (true) {
// do stuff
}
}catch (InterruptedException e) {
LOGGER.log(Level.WARN, "Interrupted!", e);
// Restore interrupted state...
Thread.currentThread().interrupt();
}
}
java interrup()函数会中断线程(本质更新线程为中断状态)。若sleep()函数检测到线程中断(interrupt()函数触发) 会抛 InterruptedException, 被catch住后线程中断状态更新为未中断(参考:https://www.codenong.com/cs106837995/)。
所以,正确处理方式需要手动再次触发一下Thread.currentThread().interrupt();