java多线程之如何正确停止线程(一)

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

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

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

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

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

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

 情形1:当线程没有阻塞时,可以正常退出线程(注意注释部分代码

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() + ":线程已结束!");
    }
}

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

情形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() + ":线程已结束!");
    }

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

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

由此可见,  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已结束!");
    }
}

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值