轉: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就是廢的
