转:https://www.jianshu.com/p/7a123f212ca1
具体参考实例:https://mp.csdn.net/console/editor/html/105405707
一、不安全的Stop()、Suspend()和Resume()
1.即刻停止run()方法中剩余的全部工作,包括在catch或finally语句中,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。
2.会立即释放该线程所持有的所有的锁,导致数据得不到同步的处理,出现数据不一致的问题。
public class Main{
public static void main(String [] args) throws Exception{
TestObject testObject = new TestObject();
Thread t1 = new Thread(){
public void run(){
try {
testObject.print("1", "2");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t1.start();
Thread.sleep(1000);
t1.stop();
System.out.println("first : " + testObject.getFirst() + " " + "second : " + testObject.getSecond());
}
}
class TestObject{
private String first = "ja";
private String second = "va";
public synchronized void print(String first, String second) throws Exception{
this.first = first;
Thread.sleep(10000);
this.second = second;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getSecond() {
return second;
}
public void setSecond(String second) {
this.second = second;
}
}
从上面的程序验证结果来看,stop()确实是不安全的。它的不安全主要是针对于第二点:释放该线程所持有的所有的锁。一般任何进行加锁的代码块,都是为了保护数据的一致性,如果在调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。
二、suspend()和resume()必须要成对出现,否则非常容易发生死锁。
suspend()和resume()必须要成对出现,否则非常容易发生死锁。
因为suspend方法并不会释放锁,如果使用suspend的目标线程对一个重要的系统资源持有锁,那么没任何线程可以使用这个资源直到要suspend的目标线程被resumed,如果一个线程在resume目标线程之前尝试持有这个重要的系统资源锁再去resume目标线程,这两条线程就相互死锁了,也就冻结线程。
举个例子:
public class Main{
public static void main(String [] args) throws Exception{
TestObject testObject = new TestObject();
Thread t1 = new Thread(){
public void run(){
testObject.print();
}
};
t1.setName("A");
t1.start();
Thread.sleep(1000);
Thread t2 = new Thread(){
public void run(){
System.out.println("B已启动,但进入不到print方法中");
testObject.print();
}
};
t2.setName("B");
t2.start();
}
}
class TestObject{
public synchronized void print(){
if(Thread.currentThread().getName().equals("A")){
System.out.println("A 线程 独占该资源了");
Thread.currentThread().suspend();
}
}
}
三、第三种结论:suspend和resume就是废的