雙重檢測鎖定的單例模式講解

package SingletonPattern;

//雙重檢查鎖機制的單例模式,在JDK1.5之後,雙重檢查鎖定才能夠正常達到單例效果
public class Demo5 {
    //volatile確保了instance的內存可見性,即當前線程在使用(use)自己工作內存中的instance的前一步,
    // 都會從主內存中刷新load(對應的read會發生在load前)一遍,確保此時是最新的值,
    //但在這裏必要的不是這個功能,因爲synchronized能夠保證可見性
    //這裏必要的是volatile禁止了指令重排序
    private static volatile Demo5 instance;
    private Demo5(){

    }
    public static Demo5 getInstance(){
        if (instance == null){                  //instance空時進入同步塊,非空時,不需要同步
            synchronized (Demo5.class){
                //如果同步塊內沒有這層檢查,則假設當兩個線程同時調用時,都會進入同步塊,一個執行,一個阻塞
                //當執行線程離開同步塊,阻塞線程拿到鎖進入同步塊,又實例化了一次
                if (instance == null){
                    instance = new Demo5();//創建對象可以分解爲如下的3行僞代碼
                    // memory=allocate(); 1:分配對象的內存空間ctorInstance(memory);
                    // ctorInstance(memory); 2:初始化對象instance=memory;
                    // instance=memory; 3:設置instance指向剛分配的內存地址
                    // 若不禁止指令重排序,可能會導致先3後2,實例化還沒做完,就提前先把instance賦值了
                    // 此時其他線程調用方法得到的實例可能是不完整的,使用時就會出錯
                    System.out.println("實例化!");
                }
            }
        }
        return instance;
    }
    public void dosomething(){
        System.out.println("我是Demo5");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章