1. 程式人生 > >為什麼Thread.stop()方法被棄用

為什麼Thread.stop()方法被棄用

在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執行緒的原因,這樣可能會導致一些難以處理的問題