在Java
的API
中明确了Thread.stop()
方法已经被弃用了,下面引用API
的介绍并结合例子展示这个方法为什么会被弃用
该方法具有固有的不安全性。用 Thread.stop 来终止线程将释放它已经锁定的所有监视器(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。stop 的许多使用都应由只修改某些变量以指示目标线程应该停止运行的代码来取代。目标线程应定期检查该变量,并且如果该变量指示它要停止运行,则从其运行方法依次返回。如果目标线程等待很长时间(例如基于一个条件变量),则应使用 interrupt 方法来中断该等待。
我个人的理解是使用Thread.stop()
会破坏线程安全,下面用一个实例展示使用stop导致线程安全被破坏了:
实例代码
/**
* 一个展示Thread.stop()方法为什么被弃用的例子
* @author RJH
* @date 2017年12月11日 下午7:48:00
*/
public class StopDemo {
public static void main(String[] args) {
StopThread thread=new StopThread();
thread.start();
try {
//休眠1秒,确保i变量自增成功
Thread.sleep(1000);
} catch (InterruptedException e) {
//一般会处理中断异常,这里作为例子就直接打印到控制台了
e.printStackTrace();
}
//暂停线程
thread.stop();
while(thread.isAlive()){//确保线程已经终止
}
//输出结果
thread.print();
}
/**
* 展示用的例子,内部对两个整数做自增
* @author RJH
* @date 2017年12月11日 下午7:48:32
*/
private static class StopThread extends Thread{
private int i=0;
private int j=0;
@Override
public void run(){
synchronized (this) {//增加同步锁,确保线程安全
++i;
try {
//休眠10秒,模拟耗时操作
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
++j;
}
}
/**
* 打印i和j
*/
public void print(){
System.out.println("i="+i+" j="+j);
}
}
}
运行结果
i=1 j=0
结果分析
StopThread
类正常运行的时候,最终调用print()方法输出的值应该为i=1 j=1
,但是由于调用了stop()
方法强制终止了线程的运行,导致i
已经自增了,但是j
并未自增。破坏了这个类的线程安全(也可以理解为破坏了数据的完整性)。
PS:这个也是不提倡强制kill线程的原因,这样可能会导致一些难以处理的问题