C#記錄(四):放棄Stop()、Suspend()和Resume()

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章