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