如何终止Java线程

Thread.stop,Thread.suspend,Thread.resume,Runtime.runFinalizersOnExit都已经被废弃了。
为什么要废弃Thread.stop?因为此函数天然的不安全。
骤然停止一个线程,会造成该线程已经占有的资源无法释放,进而引发一系列无法预知的错误。而技术上实现骤然停止后释放资源不太可行。
一种推荐的线程停止方法:while(flag)
在Thread的run函数中写成while(flag)的形式,通过控制flag来控制线程是否停止,这样是完全可控的。

然而并非所有的多线程任务都可以写成while(flag)的形式。

线程所做的任务分为两类:运行状态和非运行状态
非运行状态包括:

  • Thread.sleep
  • 正在wait
  • IO阻塞时,读文件或者网络请求

对于非运行状态:当线程处于wait或者sleep状态时,可以使用thread.interupt方法来终止线程,这样可以保证正确地停止一个线程。
当线程处于IO阻塞时,interupt是否管用取决于所在平台,Linux和Mac可以使用interupt来终止线程,windows却不能。

而当线程处于运行状态时,目前没有完美的解决方法来终止一个线程。

Thread.destroy函数一直没有实现,这个函数里面是空的。

下面看几个例子:
demo1:使用interupt叫醒正在sleep的线程

public class One {
static Runnable x = new Runnable() {
    @Override
    public void run() {
        try {
            Thread.sleep(12000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

public static void main(String[] args) {
    Thread m = new Thread(x);
    m.start();
    System.out.println("haha");
    m.interrupt();
    System.out.println("game over");
}
}

这个程序很快运行完了,根本没有用12秒。

demo2:使用interupt无法叫醒正在运行的线程

public class Two {
static Runnable x = new Runnable() {
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("haha");
        }
    }
};

public static void main(String[] args) {
    Thread m = new Thread(x);
    m.start();
    m.interrupt();
    System.out.println("over");
}
}

这个程序永远都不会停止。
在此例中,如果把while循环放在try catch内部,则能够正常跳出循环,使得interupt变得可能可行,因为当Thread正在执行System.out.println("haha");这句话时,interupt是无效的,就不会抛出异常,也就无法跳出循环。

参考资料

https://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
https://www.cnblogs.com/gpcuster/archive/2010/01/18/1650273.html

原文地址:https://www.cnblogs.com/weiyinfu/p/8124091.html