Java 如何继续中断的线程

问题描述

在开发中,我们常常会遇到需要中断线程的场景。例如,一个线程正在执行一个耗时操作,而用户又希望在执行过程中能够随时中断该操作。那么如何在 Java 中实现线程的中断呢?

解决方案

Java 提供了一种机制来中断线程,即使用interrupt()方法。当一个线程调用interrupt()方法时,如果目标线程正在执行可中断的操作(如sleep()wait()join()等),它将立即抛出一个InterruptedException异常,以提供给应用程序一个机会来处理中断请求。

下面我们来看一个具体的例子,通过线程执行一个耗时操作来演示如何中断线程。

public class InterruptExample extends Thread {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                System.out.println("Executing task " + i);
                Thread.sleep(1000); // 模拟耗时操作

                // 检查线程是否被中断
                if (Thread.interrupted()) {
                    System.out.println("Thread interrupted, exiting...");
                    return;
                }
            }
        } catch (InterruptedException e) {
            System.out.println("Thread interrupted, exiting...");
            return;
        }

        System.out.println("Task completed successfully.");
    }

    public static void main(String[] args) {
        InterruptExample thread = new InterruptExample();
        thread.start();

        // 中断线程
        try {
            Thread.sleep(5000); // 等待5秒
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上面的例子中,我们创建了一个继承自Thread的子类InterruptExample,并重写了run()方法来执行耗时操作。在run()方法中,我们使用Thread.sleep(1000)来模拟一个耗时操作。在每次循环中,我们都会检查线程是否被中断,并在中断时退出循环。

main()方法中,我们创建了一个InterruptExample线程对象,并通过thread.start()来启动线程。然后我们使用Thread.sleep(5000)来等待5秒,并调用thread.interrupt()来中断线程。

在执行过程中,如果线程被中断,Thread.sleep(1000)将立即抛出一个InterruptedException异常,然后线程将退出循环并结束执行。如果线程未被中断,则耗时操作将继续执行。

类图

classDiagram
    class InterruptExample {
        -Thread thread
        ..构造方法..
        +void run()
        +void start()
        +void interrupt()
    }

    class Thread {
        +void sleep(long millis) throws InterruptedException
        +boolean interrupted()
    }

上述类图显示了InterruptExample类和Thread类之间的关系。InterruptExample类通过继承Thread类来创建一个线程对象,并使用sleep()interrupted()方法来实现线程的中断。

代码分析

InterruptExamplerun()方法中,我们通过调用Thread.interrupted()来检查线程是否被中断。Thread.interrupted()是一个静态方法,它返回一个布尔值,表示当前线程是否被中断,并将中断状态清除。如果线程被中断,Thread.interrupted()将返回true,否则返回false

catch (InterruptedException e)块中,我们捕获到InterruptedException异常,表示线程在等待状态时被中断。在这种情况下,我们打印一条消息并返回,以提前结束线程的执行。

main()方法中,我们创建了一个InterruptExample线程对象,并通过thread.start()来启动线程。然后我们使用Thread.sleep(5000)来等待5秒,并调用thread.interrupt()来中断线程。

需要注意的是,在main()方法中使用Thread.sleep()等待5秒的目的是为了确保线程开始执行耗时操作后再中断它。否则,如果在线程启动之前就中断它,线程将不会执行任何操作,并立即退出。

流程图

pie