本文来学习如何学习优雅地中止线程?通过 Java 线程的生老病死的学习,我相信大家对线程的运行以及线程的状态有一定了解了,那么我们现在来学习中止线程:

错误的线程中止 - stop

首先来讲解一个错误的方式来中止线程 — stop:中止线程,并且清除监控器锁的信息,但是可能导致线程安全问题,JDK 不建议使用,类似的方法还有 destory,由于 JDK 从未实现该方法,在这里就不介绍了。

接下来通过一段程序来讲解为什么 stop 会导致线程安全问题?

首先定义一个线程类 StopThread

public class StopThread extends Thread {
    private int i = 0;
    private int j = 0;

    @Override
    public void run() {
        synchronized (this) {
            // 增加同步锁,确保线程安全
            ++i;
            try {
                // 休眠10秒,模拟耗时操作
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ++j;
        }
    }

    /**
     * 打印 i 和 j
     */
    public void print() {
        System.out.println("i=" + i + " j=" + j);
    }
}

这个线程做的事情就是在同步代码块中对 ij 这两个变量进行自增操作,但是在这个执行过程中会进行 10 秒的睡眠,如果在这个过程中,如果用 stop 方法将线程中止的话,会导致 ij 数据不正确,也可以说程序设计上的线程安全问题,因为主线程影响到了创建的 StopThread 线程的数据不正确性,理想的正确输出结果应该是要么全部添加成功,要么都失败,因为我们添加锁的目的就是保证操作原子性或者说想让这两个变量在操作的时候不受其他线程干扰。

下面编写 StopThreadDemo 类,来使用 stop 方法做个错误示范:

public class StopThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        StopThread thread = new StopThread();
        thread.start();
        // 休眠 1 秒,确保 i 变量自增成功
        Thread.sleep(1000);
        // 暂停线程
        thread.stop(); // 错误的终止
        while (thread.isAlive())