Java线程片——线程的关闭

210 阅读4分钟

前文再续,书接上一回。前文讲述了如何开启线程以及开启线程的三种方法。本文主要围绕如何优雅的关闭Java线程。

在我们寻求Java线程的关闭关闭方式的时候,我们也许会按住Ctrl键进入到Thread类中阅读源码,很快的我们就能找到一个stop()方法。似乎stop()方法就是结束线程的方法,但是事实恰恰与我们的猜想相反。

stop()方法太过于暴力,会把执行到一半的线程给终止了,这样线程线程资源的释放就得不到保证。通常是没有给与线程完成资源释放工作的机会,因此会导致程序工作在不确定的状态下。 

三种结束线程的方法:

  • 设置退出标志,使线程正常退出,正常地退出run()方法后线程结束。
  • 使用interrupt()方法终止线程。
  • 使用stop方法强制终止线程(不推荐使用)


使用退出标志终止线程

正常来说线程执行体run()方法执行完之后,线程就会进入死亡状态,但是在开发过程中线程通常会进入一个无限循环,长时间地执行一些监听的任务,只有在满足一定条件的时候才能结束。我们可以通过一个变量来控制循环,那他便会在下一次循环前退出run()方法。

public class MyThread extends Thread {
    public volatile boolean exit = false; 
        public void run() { 
        while (!exit){
            //do something
        }
    } 
}

在这里定义了一个由volatile 修饰的布尔值变量exit,当把exit修改成true,循环就会退出,线程也就正常关闭。volatile关键字是的exit变量在多个线程中具有可见性。

使用interrupt()方法结束线程

要中断一个Java线程,可调用线程类(Thread)对象的实例方法:interrupte();然而interrupte()方法并不会立即执行中断操作。

如果在中断时,线程正处于非阻塞状态,则将中断标志修改为true,而在此基础上,一旦进入阻塞状态,则按照阻塞状态的情况来进行处理;例如,一个线程在运行状态中,其中断标志被设置为true,则此后,一旦线程调用了wait、jion、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被清除,重新设置为false。

 我们可以总结,调用线程类的interrupted方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并根据线程状态决定是否抛出异常。因此,通过interrupted方法真正实现线程的中断原理是:开发人员根据中断标志的具体值,来决定如何退出线程。

public class ThreadTest {
 
    static class MyThread extends Thread {
        @Override
        public void run() {
            while (!isInterrupted()){ //非阻塞过程中通过判断中断标志来退出
                try{
                    Thread.sleep(5*1000);//阻塞过程捕获中断异常来退出
                }catch(InterruptedException e){
                    e.printStackTrace();
                    System.out.println("ThreadSafe:run()"+e.getMessage());
                    break;//捕获到异常之后,执行break跳出循环。
                }
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        Thread thread = new ThreadSafe();
        thread.start();
        System.out.println("在50秒之内按任意键中断线程!");
        System.in.read();
        thread.interrupt();
        Thread.sleep(5000);
        System.out.println("线程已经退出!thread.is" + thread.isAlive());
    }
 
}

运行结果如下:


例子中,启动线程,并在线程调用sleep()方法进入阻塞状态的时候,主线程调用了MyThread的interrupt()方法,此时线程就会跑出InterruptdException结束run()方法,从而结束线程。从最后一句主线程打印中看出,MyThread结束了, 已经死亡。

That's all Thank you~

                                                         ----- End -----

                                                              更多好文

                                                       请扫描下面二维码

                                                              欢迎关注~