• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            colorful

            zc qq:1337220912

             

            Double-checked locking真的有效嗎?

            Double-checked locking真的有效嗎?

            作者: zsxwing 日期: 2011-04-29 10:48:06

            在很多設計模式的書籍中,我們都可以看到類似下面的單例模式的實現代碼,一般稱為Double-checked locking(DCL)

            01public class Singleton {
            02 
            03    private static Singleton instance;
            04 
            05    private Singleton() {
            06        // do something
            07    }
            08 
            09    public static Singleton getInstance() {
            10        if (instance == null) {//1
            11            synchronized (Singleton.class) {//2
            12                if (instance == null) {//3
            13                    instance = new Singleton();//4
            14                }
            15            }
            16        }
            17        return instance;
            18    }
            19}

            這樣子的代碼看起來很完美,可以解決instance的延遲初始化。只是,事實往往不是如此。

            問題在于instance = new Singleton();這行代碼。

            在我們看來,這行代碼的意義大概是下面這樣子的

             

             

            	mem = allocate();             //收集內存 
            ctorSingleton(mem); //調用構造函數
            instance = mem; //把地址傳給instance
            	

             

            這行代碼在Java虛擬機(JVM)看來,卻可能是下面的三個步驟(亂序執行的機制):

             

            	mem = allocate();             //收集內存 
            instance = mem; //把地址傳給instance
            	ctorSingleton(instance);      //調用構造函數

             

            下面我們來假設一個場景。

            1. 線程A調用getInstance函數并且執行到//4。但是線程A只執行到賦值語句,還沒有調用構造函數。此時,instance已經不是null了,但是對象還沒有初始化。
            2. 很不幸線程A這時正好被掛起。
            3. 線程B獲得執行的權力,然后也開始調用getInstance。線程B在//1發現instance已經不是null了,于是就返回對象了,但是這個對象還沒有初始化,于是對這個對象進行操作就出錯了。

            問題就出在instance被提前初始化了。

            解決方案一,不使用延遲加載:

            01public class Singleton {
            02 
            03    private static Singleton instance = new Singleton();
            04 
            05    private Singleton() {
            06        // do something
            07    }
            08 
            09    public static Singleton getInstance() {
            10        return instance;
            11    }
            12}

            JVM內部的機制能夠保證當一個類被加載的時候,這個類的加載過程是線程互斥的。這樣當我們第一次調用getInstance的時候,JVM能夠幫我們保證instance只被創建一次,并且會保證把賦值給instance的內存初始化完畢。

            解決方案二,利用一個內部類來實現延遲加載:

            01public class Singleton {
            02 
            03    private Singleton() {
            04        // do something
            05    }
            06 
            07    private static class SingletonContainer {
            08        private static Singleton instance = new Singleton();
            09    }
            10 
            11    public static Singleton getInstance() {
            12        return SingletonContainer.instance;
            13    }
            14}

            這兩種方案都是利用了JVM的類加載機制的互斥。

            方案二的延遲加載實現是因為,只有在第一次調用Singleton.getInstance()函數時,JVM才會去加載SingletonContainer,并且初始化instance。

            不只Java存在這個問題,C/C++由于CPU的亂序執行機制,也同樣存在這樣的問題。

            抱歉,我之前的理解有誤,DCL在Java中失效的原因是JIT比較激進的優化導致的,在C/C++并不會由于CPU的亂序執行(調用構造函數和賦值這兩個操作對CPU來說絕對不會亂序的)產生這個問題。

            暫時不知道Java對于這個問題是否修復了。

            posted on 2012-03-31 16:53 多彩人生 閱讀(327) 評論(0)  編輯 收藏 引用

            導航

            統計

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久se精品一区精品二区| 丰满少妇人妻久久久久久| 久久综合色区| 久久人人爽人人爽人人片AV不 | 久久国产精品99国产精| 99久久人妻无码精品系列蜜桃| 伊人久久精品线影院| 2021国产精品午夜久久| 91性高湖久久久久| 国产亚洲精品久久久久秋霞| 亚洲国产成人久久精品影视| 精品无码久久久久国产动漫3d| 欧美精品一本久久男人的天堂| 久久国产欧美日韩精品免费| 狠狠色噜噜狠狠狠狠狠色综合久久 | 久久九九久精品国产免费直播| 日韩人妻无码一区二区三区久久| 色噜噜狠狠先锋影音久久| 亚洲AV日韩精品久久久久久| 国产日韩久久久精品影院首页 | 久久精品国产一区二区电影| 久久成人国产精品| 久久精品国产亚洲AV忘忧草18| 久久99精品国产99久久6| 人妻久久久一区二区三区| 一本色道久久88综合日韩精品 | 97久久精品无码一区二区天美| 久久人人爽人人爽人人av东京热| 精品多毛少妇人妻AV免费久久| 久久99精品综合国产首页| 人妻久久久一区二区三区| 蜜臀久久99精品久久久久久小说| 欧美黑人激情性久久| 午夜精品久久久久9999高清| 久久九九久精品国产免费直播| 久久AⅤ人妻少妇嫩草影院| 久久综合久久综合九色| 成人精品一区二区久久久| 国产成人精品久久| 久久久久九国产精品| 色综合久久中文字幕综合网|