代码评审——InterruptedException异常处理

问题描述

在程序开发过程中,不可避免的会使用到多线程。当为了避免出现异常时,也会进行相应的代码处理并捕获、抛出InterruptedException异常。在代码评审过程中,经常会出现捕获InterruptedException异常,同时还存在为了方便仅用Exception进行捕获,虽然两者都进行了输出堆栈,但没有任何后续处理的情况。

代码如下:

try {
	Thread.sleep(10);
	//do something
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

此时,使用静态代码扫描工具,会出现以下提示:
在这里插入图片描述
如果仅把Exception改为InterruptedException,依然会提示

“InterruptedException” should not be ignored


原因分析:

静态代码扫描工具给出的解释为:

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.

详细分析:
首先,看下该异常在java文档的定义:

Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Occasionally a method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception.

再看这个异常,当抛出 InterruptException 异常后会清除中断标志,即把中断标志设为false。程序捕获 InterruptException 并吞下它,此时本质上阻止了任何更高级别的方法/线程组注意到中断。这可能就会导致出现程序问题。


解决方案:

解决方式比较简单。首先看下java文档对此的说明:

For this technique to work, it’s critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the InterruptedException is not declared to throw this (checked) exception, then it should “reinterrupt itself” with the following incantation:
Thread.currentThread().interrupt();

只需要在捕获异常后,重新设置中断标志,让更高级别的中断处理程序会注意到它并且可以正确处理它。

try {
	Thread.sleep(10);
	//do something
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
	Thread.currentThread().interrupt();
}

你可能感兴趣的:(代码评审,java,代码复审)