首页 > 编程笔记 > Java笔记 阅读:2

Java停止线程的2种方法(附带示例)

在 Java 中,停止一个正在运行的线程需要谨慎处理,因为错误停止线程可能导致程序状态不一致或资源没有被正确释放。

Java 早期版本中提供了 stop() 方法来停止线程,但是这个方法现在已经被废弃了,它并不安全,因为调用 stop() 方法会强制终止线程,可能导致线程资源未被正确释放,从而导致程序出现不可预估的行为,不推荐使用。

下面我们推荐两种正确停止线程的方式。

volatile标志停止线程

可以定义一个 volatile 的 boolean 型变量来指示线程何时应该停止,线程会定期检查这个变量的值,并在变量状态指示停止时有序地终止。

使用 volatile 标志停止线程的原理比较简单,在线程执行的核心逻辑中,不断地检查标志位,如果标志位被设置为停止,则线程退出执行。
public class StoppableRunnable implements Runnable {
    private volatile boolean isStopped = false;
    public void requestStop() {
        isStopped = true;
    }
    @Override
    public void run() {
        while (!isStopped) {
            // TODO执行任务代码逻辑
            // 在适当的位置检查标志
            if (Thread.interrupted()) { // 响应中断请求
                break;
            }
        }
        // 清理资源和状态
        // ...
    }
}
// 使用StoppableRunnable类
StoppableRunnable stoppable = new StoppableRunnable();
Thread thread = new Thread(stoppable);
thread.start();
// 当需要停止线程时执行
stoppable.requestStop();
需要注意,在多线程环境下,使用标志位停止线程可能存在并发问题,我们可以使用 synchronized 关键字来同步对标志位的访问,保证线程间的可见性和互斥性。

interrupt()方法停止线程

Thread 类提供了 interrupt() 方法来中断线程。使用 interrupt() 方法中断线程的原理是,当一个线程调用另一个线程的 interrupt() 方法时,被调用线程会收到一个中断信号。被调用线程可以通过检查中断状态来决定是否停止执行。

被调用线程的中断状态是通过一个内部的 boolean 型变量来表示的,调用 interrupt() 方法会将这个变量设置为 true。被调用线程可以通过调用 isInterrupted() 方法来检查中断状态,并在适当的时候停止执行。
public class InterruptibleRunnable implements Runnable {
    @Override
    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted()) {
                // TODO执行任务代码逻辑
                // 如果任务包含可中断的阻塞方法(如 Thread.sleep()),它将抛出 Inter-ruptedException异常
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            // 恢复中断状态以便在后续执行中继续检查
            Thread.currentThread().interrupt();
            // 清理资源和状态
            // ...
        }
    }
}
// 使用InterruptibleRunnable类
Thread thread = new Thread(new InterruptibleRunnable());
thread.start();
// 当需要停止线程时
thread.interrupt();
interrupt() 方法并不会直接停止线程,它只是设置了线程的中断状态。被调用线程需要自行决定如何对中断信号做出响应。如果线程处于阻塞状态(如调用 sleep()、wait()、join() 等方法),调用 interrupt() 方法会抛出 InterruptedException 异常,可以通过捕获该异常并进行相应处理来停止线程。

相关文章