停止线程,也许我们首先会有一种错感,觉得使用Thread.stop()或者Thread.interrupt()与Thread.interrupted()等组合就能退出线程了。可是在实际运用过程中,这样真的可以达到安全退出线程吗?下面就由我带大家逐一分析实例,最后顺便举个例说明如何才能安全的退出线程。

1、Thread.stop()方式停止线程,会发生什么呢?

      不用多说,直接简单粗暴的方式,肯定就是直接上代码啦,如图:

Java 停止一个线程 java如何停止线程_Java 停止一个线程

Java 停止一个线程 java如何停止线程_System_02

Java 停止一个线程 java如何停止线程_Java 停止一个线程_03

通过运行结果:可以看到执行stop()方法退出线程,会无法预料到线程到底执行到哪一步就被意外终止了,从而无法保证执行完一个完成操作流程(比如:循环体一次自上而下的逻辑过程),所以属于非法终止线程。该方法已被废弃,不推荐使用。

2、Thread.interrupt()方式停止线程,又会发生什么呢?

 继续简单粗暴吧,分情况讨论:

注意注释部分代码)

package com.xxl.job.myThread;

public class WrongStopThread extends Thread {

    public static void main(String[] main) {
        WrongStopThread wrongStopThread = new  WrongStopThread();
        wrongStopThread.setName("myThread");
        System.out.println("线程开始启动......");
        wrongStopThread.start();
        try {
            Thread.sleep(1000);  //休眠一下,模拟效果;否则无法进入线程循环体
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        wrongStopThread.interrupt();  //停止线程
        System.out.println("main application已结束!");
    }

    @Override
    public void run() {
        while(!this.isInterrupted()){  //这里相当于也是设置一个线程退出标志
            System.out.println(this.getName() + ": is running .......");
           /* try {
                Thread.sleep(3000); //设置休眠3秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
        }
        System.out.println(this.getName() + ":线程已结束!");
    }
}

流程能走完,线程可以正常的退出,运行结果:

Java 停止一个线程 java如何停止线程_java多线程如何正确退出_04

情形2: 当注释部分代码块可用时,即

@Override
    public void run() {
        int count = 0;
        while(!this.isInterrupted()){  //这里相当于也是设置一个线程退出标志
            System.out.println(this.getName() + ": is running .......");
            try {
                Thread.sleep(3000); //设置休眠3秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.getName() + ":count = " + count++);
        }
        System.out.println(this.getName() + ":线程已结束!");
    }

运行结果抛出了异常,显示线程一直在跑,并没有结束:

Java 停止一个线程 java如何停止线程_Java 停止一个线程_05

具体原因可以看具体API文档说明:

Java 停止一个线程 java如何停止线程_Java 停止一个线程_06

由此可见,  Thread.interrupt() 并不能保证线程能正常退出,也不建议采用来停止线程。

 

3、最后说一下如何安全停止线程,可采用通过设置volatile修饰的退出标志位来保证线程安全退出

不用多说,还是直接上代码

package com.xxl.job.myThread;

public class StopThread extends Thread {

    volatile boolean isStop = false; //线程退出标志

    @Override
    public void run() {
        int count = 0;
        while(!isStop){ //安全退出判断
            System.out.println(this.getName() + ": is running .......");
            try {
                Thread.sleep(1000); //设置休眠1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.getName() + ":count = " + count++);
        }
        System.out.println(this.getName() + ":线程已结束!");
    }

    public static void main(String[] main) {
        StopThread stopThread = new  StopThread();
        stopThread.setName("myThread");
        System.out.println("线程开始启动......");
        stopThread.start();
        try {
            Thread.sleep(1000);  //休眠一下,模拟效果
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //stopThread.stop();  //停止线程
        stopThread.isStop = true; //停止线程
        System.out.println("main application已结束!");
    }
}

就这样,如有不恰当之处,请不吝赐教。