Java报错”InterruptedException”的原因以及解决办法

  • Post category:Java

Java中的InterruptedException是一个Checked Exception,它表示一个线程正在等待某个操作完成时被另一个线程中断。当一个线程调用sleep()、wait()、join()等方法时,如果另一个线程调用了该线程的interrupt()方法,则该线程就会被唤醒,然后抛出InterruptedException异常。这种通过interrupt()方法来中断线程的方式是Java中一种常见的线程控制机制。

解决InterruptedException的方法通常是调用catch块中的Thread.currentThread().interrupt()方法重新中断当前线程,并且在catch块之后添加相应的处理逻辑,如日志记录,资源清理等。下面是两个具体的示例:

示例1:使用Thread.currentThread().interrupt()重新中断线程

Thread t = new Thread(() -> {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        System.out.println("线程中断了");
    }
});
t.start();
// 等待2秒后中断线程
try {
    Thread.sleep(2000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
t.interrupt();

在上面的示例中,我们创建了一个新线程t并让它休眠5秒钟。我们在t的run()方法中捕获了InterruptedException异常并调用了Thread.currentThread().interrupt()重新中断线程,然后输出了一条中断信息。在主线程中等待2秒后,我们中断了线程t。运行上面的代码后可以看到,线程t的运行被中断了,并且输出了一条中断信息。

示例2:在处理InterruptedException时清理资源

class MyTask implements Runnable {
    private Thread worker;
    private boolean isRunning = true;

    public MyTask() {
        worker = new Thread(this);
        worker.start();
    }

    public void run() {
        while (isRunning) {
            try {
                System.out.println("MyTask运行中...");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("MyTask被中断");
                // 在这里清理资源...
                isRunning = false;
            }
        }
    }

    public void stop() {
        isRunning = false;
        worker.interrupt();
    }
}

public class Main {
    public static void main(String[] args) {
        MyTask task = new MyTask();
        // 程序运行10秒钟后停止
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        task.stop();
    }
}

在上面的示例中,我们定义了一个MyTask类,它表示一个长时间运行的任务。在MyTask的run()方法中,我们使用了一个循环和Thread.sleep()方法模拟长时间运行的任务,并在catch块中添加了清理资源的代码,最后将isRunning标志置为false并重新中断线程。在Main类中,我们创建了一个MyTask实例并让它运行10秒钟后停止,我们将停止操作封装在MyTask的stop()方法中,调用该方法即可停止任务。运行上面的代码后可以看到,MyTask在捕获到InterruptedException异常后停止了运行,并输出了一条中断信息。