• <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

            在很多設(shè)計(jì)模式的書籍中,我們都可以看到類似下面的單例模式的實(shí)現(xiàn)代碼,一般稱為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的延遲初始化。只是,事實(shí)往往不是如此。

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

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

             

             

            	mem = allocate();             //收集內(nèi)存 
            ctorSingleton(mem); //調(diào)用構(gòu)造函數(shù)
            instance = mem; //把地址傳給instance
            	

             

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

             

            	mem = allocate();             //收集內(nèi)存 
            instance = mem; //把地址傳給instance
            	ctorSingleton(instance);      //調(diào)用構(gòu)造函數(shù)

             

            下面我們來假設(shè)一個(gè)場景。

            1. 線程A調(diào)用getInstance函數(shù)并且執(zhí)行到//4。但是線程A只執(zhí)行到賦值語句,還沒有調(diào)用構(gòu)造函數(shù)。此時(shí),instance已經(jīng)不是null了,但是對象還沒有初始化。
            2. 很不幸線程A這時(shí)正好被掛起。
            3. 線程B獲得執(zhí)行的權(quán)力,然后也開始調(diào)用getInstance。線程B在//1發(fā)現(xiàn)instance已經(jīng)不是null了,于是就返回對象了,但是這個(gè)對象還沒有初始化,于是對這個(gè)對象進(jìn)行操作就出錯(cuò)了。

            問題就出在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內(nèi)部的機(jī)制能夠保證當(dāng)一個(gè)類被加載的時(shí)候,這個(gè)類的加載過程是線程互斥的。這樣當(dāng)我們第一次調(diào)用getInstance的時(shí)候,JVM能夠幫我們保證instance只被創(chuàng)建一次,并且會保證把賦值給instance的內(nèi)存初始化完畢。

            解決方案二,利用一個(gè)內(nèi)部類來實(shí)現(xiàn)延遲加載:

            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的類加載機(jī)制的互斥。

            方案二的延遲加載實(shí)現(xiàn)是因?yàn)椋挥性诘谝淮握{(diào)用Singleton.getInstance()函數(shù)時(shí),JVM才會去加載SingletonContainer,并且初始化instance。

            不只Java存在這個(gè)問題,C/C++由于CPU的亂序執(zhí)行機(jī)制,也同樣存在這樣的問題。

            抱歉,我之前的理解有誤,DCL在Java中失效的原因是JIT比較激進(jìn)的優(yōu)化導(dǎo)致的,在C/C++并不會由于CPU的亂序執(zhí)行(調(diào)用構(gòu)造函數(shù)和賦值這兩個(gè)操作對CPU來說絕對不會亂序的)產(chǎn)生這個(gè)問題。

            暫時(shí)不知道Java對于這個(gè)問題是否修復(fù)了。

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


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            99国产精品久久久久久久成人热| 精品国产乱码久久久久久郑州公司| 久久亚洲国产精品一区二区| 94久久国产乱子伦精品免费| 久久午夜综合久久| 久久天天躁夜夜躁狠狠| 久久久久久综合一区中文字幕 | 丰满少妇高潮惨叫久久久| 久久亚洲综合色一区二区三区| 欧洲国产伦久久久久久久| 久久久av波多野一区二区| 亚洲国产成人久久综合一区77| 精品国产乱码久久久久久1区2区 | 久久精品无码专区免费青青| 精品久久久久久久久久中文字幕 | 国产精品久久久久jk制服| 亚洲精品无码专区久久同性男| 久久综合亚洲欧美成人| 久久久国产视频| 欧美无乱码久久久免费午夜一区二区三区中文字幕| 亚洲精品国产第一综合99久久| 久久福利青草精品资源站| 亚洲色婷婷综合久久| 中文成人无码精品久久久不卡| 四虎国产精品免费久久5151| 久久国产精品成人影院| 久久精品国产男包| 久久久久99这里有精品10| 亚洲国产精品无码久久久久久曰| 99久久www免费人成精品| 久久九九青青国产精品| 国产亚洲精久久久久久无码| 亚洲国产另类久久久精品| 精品多毛少妇人妻AV免费久久| 久久精品视频一| 久久国产AVJUST麻豆| 伊人久久大香线蕉综合网站| 久久久久久久久久久精品尤物| 色综合久久中文字幕综合网| 理论片午午伦夜理片久久| 久久露脸国产精品|