小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

GoF設計模式之五 Singleton- -

 wtf_soft 2005-07-22

 

                                      

    A5) Singleton(單態(tài)模式)
    定義:保證一個類只存在一個實例,并提供一個全局訪問的指針。
    這個也是非常常見的模式,可以說很難在一個項目中不使用這個模式。對于全局變量來說,唯一和同步是至關重要的,一般來說以下面的這種方式來實現(xiàn)。
    public class Singleton {
        private Singleton(){}
        private static Singleton instance = new Singleton();
        public static Singleton getInstance() {
        return instance;
        }
    }

    第一行必須用private的構造函數(shù),這樣才能防止別的class生成Singleton的實例,而第二行的static定義讓變量instance在所有Singleton實例中是唯一的(當然,這個例子實際上只有一個實例),那么每次通過getInstance()得到的變量instance就是Singleton的唯一實例。還有一種方法,如下:
    public class Singleton {
        private Singleton(){}
        private static Singleton instance = null;
        public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
        }
    }

    這種方法叫做lazy initialization技術,不過關于這種技術的爭議很多,牽涉到double-checked locking(DCL)問題。關于這個問題,稍微解釋一下,具體我也不是太明確,有興趣可以另外研究。編譯器在編譯執(zhí)行命令的時候,由于會使用代碼優(yōu)化,在synchronized段中的代碼就有可能會被提前執(zhí)行以加快代碼效率。這個時候,也就是instance = new Singleton();這部分語句可能被預先優(yōu)化執(zhí)行,那么它的唯一性也就不能保證了。雖然還只是在理論上推論這個結果,并沒有用事實來驗證這一說法,現(xiàn)在也沒發(fā)現(xiàn)這個方法造成的不良后果,但是,我覺得還是推薦第一種方法,簡單而容易理解。
    注:感謝rwyx的指點,因為以前理解有偏差,所以將上面部分刪除后重新改寫。
    這種方法叫做lazy initialization技術,使用了synchronized關鍵字,不過這種方法的系統(tǒng)開銷比較大,所以還是推薦地一種方法,簡單而且效率高,最好在定義時追加final關鍵字。
    關于Singleton,在C++/C#等語言中會用到一種叫做double-checked的技術,目的是為了解決lazy initializtion技術中同步代碼效率低的問題。具體實現(xiàn)如下:
    public static Singleton getInstance() { 
        if (instance == null) { 
            synchronized { 
                if (instance == null) {instance = new Singleton();} 
            } 
        } 
        return instance; 
    } 
    即在同步前做一次判斷,這樣只有第一次時會進入同步段,這樣效率也很高。不過這種方法在java中卻是錯誤的。因為java語言規(guī)范和C++/C# 等不同,是一個非常靈活的規(guī)范。java編譯器可以自由地重排變量的初始化和訪問順序,以提高運行時效率;同時java中的變量訪問是可以被自動緩存到寄存器的,這也導致潛在的JIT 編譯器相關的依賴性錯誤。每個編譯器可能有不同的實現(xiàn)方法,同樣的代碼在不同編譯器和執(zhí)行環(huán)境下可能有不同的表現(xiàn)。解決的辦法有很多,使用線程局部存儲(ThreadLocal)來保存instance變量,或者使用volatile關鍵字來定義instance,強制java編譯器不進行優(yōu)化。DCL參考資料: http://www./User8/flier_lu/blog/1620823.html


   參考:
1、 http://www./designpatterns/singleton.htm(中文、java實例)
2、 http://www./Patterns/PatternSingleton.aspx(英文、C#實例、UML)
3、 http://www./tech/DesignPattern/Singleton.html(日文、java實例、UML)推薦

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多