Sonar:Either re-interrupt this method or rethrow the “InterruptedException“ that can be caught here.
  NiPpzTR2CXqv 2023年12月02日 39 0


如题,错误提示 Either re-interrupt this method or rethrow the "InterruptedException" that can be caught here. 的原因是因为没有在捕获 InterruptedException 异常后重新调用当前线程的 interrupt() 方法。

本文解释为什么需要在 catch 代码块中捕获 InterruptedException 后再次调用线程的 interrupt() 方法。

先看如下代码示例:

/**
 * 测试ThreadInterrupted的Demo
 *
 * @author 单红宇
 */
@Slf4j
public class ThreadInterruptedDemo {

    /**
     * main 方法
     *
     * @param args args
     * @throws InterruptedException InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Thread myThread = new MyThread();
        myThread.setName("MyThread");
        myThread.start();
        Thread.sleep(100);
        log.info("主动调用 MyThread 的 interrupt 方法 ...");
        myThread.interrupt();
    }
}

@Slf4j
class MyThread extends Thread {

    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        //打印当前线程是否被中断
        log.info("线程 {} interrrupted 的状态为: {}", threadName, isInterrupted());
        while (!isInterrupted()) {
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            log.info(threadName + " is running");
            //打印当前线程是否被中断
            log.info("线程 {} 循环体内打印 interrrupted 状态为: {}", threadName, isInterrupted());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                //哪怕你处理并记录了异常,sonar也会报Either re-interrupt this method or rethrow the "InterruptedException"
                //被外界中断你后,再次打印当前线程是否被中断
//                Thread.currentThread().interrupt();
                log.info("线程 {} InterruptedException 打印 interrrupted 状态为: {}", threadName, isInterrupted());
            }
            log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        }
        log.info("线程 {} 结束,此时 interrrupted 状态为: {}", threadName, isInterrupted());
    }

}

先解释一下以上代码的基本逻辑和运行结果:
1、开启一个子线程
2、在主线程中调用了子线程的 interrupt() 方法试图终止子线程
3、实际运行结果是:子线程的循环没有被结束,永远运行下去

初步查看代码你可能会有一个疑问:“不是主动调用了子线程的 interrupt() 方法了吗,为什么 while 中判断 isInterrupted() 的状态还是 true 不会结束循环呢?”

其实这跟线程 interrupt() 的处理机制有关,当你主动调用 interrupt() 后,会触发 InterruptedException 异常,但是线程在抛出 InterruptedException 异常时,会重置 interrupt 的状态为 false。所以 while 会一直执行下去。

回到本文标题,Sonar 的意思就是检测到我们的代码在捕获 InterruptedException 后没有再次设置线程的 interrupt 状态为 true,所以进行了错误提醒。这么提醒是为了告诉我们,在异常被捕获后,应该重新设置 interrupt 状态为 true,为后续判断 interrupt 状态的地方使用(在本文示例中就是 while 的地方会继续使用),以确保代码逻辑的正确。

最后,你可以去掉 Thread.currentThread().interrupt(); 这一行的注后,再重新运行代码,就会发现正常了。


(END)


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月02日 0

暂无评论

推荐阅读
NiPpzTR2CXqv