SonarQube代码审查-InterruptedException | ExecutionException异常

1. 现象描述

 如图,在执行SonarQube检查时,提示异常不能被忽略。

2. 分析及依据

2.1 信息判断的依据或规则

这条信息提示我们,在处理多线程编程时,InterruptedException 和 ThreadDeath 这两种异常不应该被忽视。这是基于多线程编程的最佳实践,因为这两种异常涉及到线程的中断和终止机制,如果不正确处理,可能会导致线程无法正常结束或资源无法正确释放。

2.2 为什么会出现这两种异常

  1. InterruptedException
    • 当一个线程在等待、休眠或其他阻塞状态时,如果另一个线程调用了该线程的 interrupt() 方法,则正在阻塞的线程会抛出一个 InterruptedException
    • 这个异常的出现意味着线程被中断,通常是为了响应某种外部事件或请求,需要立即停止当前的操作。
  2. ThreadDeath
    • ThreadDeath 是 Thread 类的一个静态内部类,表示线程已经被请求终止。
    • 通常情况下,通过调用线程的 stop() 方法(虽然 stop() 方法已经被废弃,因为它是不安全的),可以触发 ThreadDeath 异常。但更常见的做法是通过线程间的协作(如通过共享变量或中断机制)来优雅地终止线程。

2.3 为什么不能被忽视

  • InterruptedException
    • 如果不处理 InterruptedException,线程可能会继续执行原本被中断的操作,这违背了中断的初衷。
    • 另外,如果不重新设置线程的中断状态(通过 Thread.currentThread().interrupt()),线程可能无法响应后续的中断请求。
  • ThreadDeath
    • 虽然 ThreadDeath 通常不会由应用程序代码直接处理(因为它是 Error 的子类,而不是 Exception),但如果不优雅地终止线程,可能会导致资源泄露、数据不一致等问题。
    • 使用 stop() 方法强制终止线程尤其危险,因为它会立即停止线程的运行,不会执行任何清理操作。

3. 修复建议

  • InterruptedException
    • 在捕获 InterruptedException 后,通常应该重新设置中断状态(通过 Thread.currentThread().interrupt()),以便线程能够响应后续的中断请求。
    • 根据业务逻辑,可能需要执行一些清理操作或安全地退出当前操作。
  • ThreadDeath
    • 尽量避免使用 stop() 方法。相反,应该使用线程间的协作机制(如中断、共享变量等)来优雅地终止线程。
    • 可以在需要的地方捕获 ThreadDeath(虽然不常见),但更常见的是通过其他机制(如中断)来终止线程,并在适当的时机进行资源清理。

4. 模拟验证

4.1 模拟InterruptedException

public class InterruptedExceptionExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                System.out.println("Thread is going to sleep...");
                Thread.sleep(10000); // 模拟长时间等待
            } catch (InterruptedException e) {
                System.out.println("Thread was interrupted!");
                // 重新设置中断状态
                Thread.currentThread().interrupt();
            }
            System.out.println("Thread is exiting...");
        });

        thread.start();
        try {
            Thread.sleep(1000); // 主线程等待一秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt(); // 中断子线程
    }
}

4.2 模拟 ThreadDeath(不推荐直接模拟,但可以通过中断来演示线程终止)

虽然 ThreadDeath 通常不会直接处理,但可以通过模拟中断来展示线程如何优雅地终止。

public class ThreadDeathExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                // 模拟一些工作
                System.out.println("Thread is working...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("Thread was interrupted, exiting...");
                    // 清理操作可以在这里进行
                    Thread.currentThread().interrupt(); // 重新设置中断状态(可选)
                    return;
                }
            }
            System.out.println("Thread has exited gracefully.");
        });

        thread.start();
        try {
            Thread.sleep(3000); // 主线程等待几秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt(); // 中断子线程以模拟终止
    }
}

------------------------------------  本文完  ------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

探_无止境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值