<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Head First Pattern之單例模式

    Posted on 2008-09-14 15:40 Lv Yuanfang 閱讀(443) 評論(0)  編輯  收藏

    多線程環境下的單例模式實現

    ----Head First Pattern之單例模式



    單例模式我想大家都比較熟悉,就是在JVM運行期間一個類只有一個實例,任何時候都是取得同一個實例,也就是一個全局變量了。
    單例模式分懶漢式和餓漢式,但是懶漢式的單例在多線程環境下會有同步的問題,下面詳細介紹了用3中方法來解決此問題。
    單例模式具有以下幾個特點:
    1.JVM運行期間有且只有一個實例
    2.構造函數是私有的
    3.通過一個靜態工廠方法來獲得唯一的實例
    4.累內部有一個私有靜態實例,通過靜態工廠方法創建后,每次再調用靜態工廠方法,返回的都是同一個實例

    餓漢式:
    public class Singleton{
    ??? private static Singleton uniqueInstance = new Singleton();
    ??? // 其他實例變量
    ??? private Singleton(){}
    ??? public static Singleton getInstance(){
    ?? ???? return uniqueInstance;
    ?? ?}
    ?? ?
    ??? // 其他方法
    }

    懶漢式:
    public class Singleton{
    ??? private static Singleton uniqueInstance;
    ??? // 其他實例變量
    ??? private Singleton(){}
    ??? public static Singleton getInstance(){
    ?? ???? if(uniqueInstance == null){
    ?? ??? ???? uniqueInstance = new Signleton();
    ?? ??? ?}
    ?? ???? return uniqueInstance;
    ?? ?}
    ?? ?
    ??? // 其他方法
    }

    多線程環境下的單例模式:
    上面的代碼就是最基本的單例模式示例代碼。但是懶漢式單例有一個問題,因為要保證有且僅有一個實例,如果在多線程環境下調用Singleton.getInstance(),就可能會有多個實例!為了解決多線程訪問的問題,有3種解決方法供選擇:

    1.靜態工廠方法加同步關鍵字,這種方法是在對性能要求不高的情況下采用。
    public class Singleton{
    ??? private static Singleton uniqueInstance;
    ??? // 其他實例變量
    ??? private Singleton(){}
    ??? public static synchronised Singleton getInstance(){
    ?? ???? if(uniqueInstance == null){
    ?? ??? ???? uniqueInstance = new Signleton();
    ?? ??? ?}
    ?? ???? return uniqueInstance;
    ?? ?}
    ?? ?
    ??? // 其他方法
    }

    2.始終用餓漢式單例
    public class Singleton{
    ??? private static Singleton uniqueInstance = new Singleton();
    ??? // 其他實例變量
    ??? private Singleton(){}
    ??? public static Singleton getInstance(){
    ?? ???? return uniqueInstance;
    ?? ?}
    ?? ?
    ??? // 其他方法
    }
    餓漢式的方法,會依賴于JVM在加載類的時候,就創建唯一的實例。在每個線程訪問getInstance方法前,唯一實例已經被創建。

    3.用雙檢查鎖來減少懶漢式中靜態方法getInstance的同步開銷
    對public static synchronised Singleton getInstance()的每次調用,都需要同步,而雙檢查鎖的方式只是在第一次創建實例時同步,其他時候并不需要同步。
    public class Singleton{
    ??? private volatile static Singleton uniqueInstance;
    ??? private Singleton(){}
    ??? public static Singleton getInstance(){
    ?? ???? if(uniqueInstance == null){
    ?? ??? ???? synchronised(Singleton.class){
    ?? ??? ??? ???? if(uniqueInstance == null){
    ?? ??? ??? ??? ??? ??? uniqueInstance = new Singleton();
    ?? ??? ??? ??? ?}
    ?? ??? ??? ?}

    ?? ??? ?}
    ?? ???? return uniqueInstance;
    ?? ?}
    }

    如果調用時實例為null,則進入同步區塊,此時再進行判斷,如果還為null,就創建唯一的實例。有可能在一個線程在 if(uniqueInstance == null) 后進入同步區塊前,另一個線程恰好已經創建成功并從同步區塊中出來,這就需要進入同步區塊后,再做uniqueInstance是否為null的判斷。
    同時uniqueInstance需要加volatile關鍵字,保證在創建單例實例時,多個線程能正確處理uniqueInstance變量。

    注意:
    雙檢查鎖的方式在Java1.4及1.4以前版本不能工作!!因此雙檢查鎖只能在Java 5及以上版本才可以使用。
    記得Effictive Java中也提到過雙檢查鎖,也說不能在Java1.4中使用。
    原因是Java 1.4及以前的JVM中對volatile關鍵字的實現允許對雙檢查鎖不合適的同步。(誰能幫我再深入解釋下?)原文是:
    Unfortunately, in Java version 1.4 and earlier, many JVMs contain implementations of the volatile keyword that allow improper synchronization for double-checked locking. If you must use a JVM other than Java 5, consider other methods of implementing your Singleton.



    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    posts - 11, comments - 2, trackbacks - 0, articles - 0

    Copyright © Lv Yuanfang

    主站蜘蛛池模板: 亚洲成a人片77777老司机| 亚洲阿v天堂在线| 亚洲日本人成中文字幕| 久久99国产综合精品免费| 亚洲成AV人片在线观看| 永久在线观看免费视频| 亚洲va久久久噜噜噜久久男同| 你懂得的在线观看免费视频| 在线观看亚洲av每日更新| 青青操免费在线观看| 亚洲色偷偷偷鲁综合| 未满十八18禁止免费无码网站| 亚洲AV电影院在线观看| 2019中文字幕在线电影免费 | 国产精品黄页在线播放免费| 亚洲日本在线电影| 国产在线19禁免费观看国产| 春意影院午夜爽爽爽免费| 亚洲日韩欧洲无码av夜夜摸| 日韩免费电影网址| 亚洲国产成人久久三区| 亚洲精品无码不卡在线播放| 8x8×在线永久免费视频| 亚洲精品福利网泷泽萝拉| 免费在线观看h片| 色老板亚洲视频免在线观| 国产v精品成人免费视频400条| 亚洲欧美日韩中文字幕一区二区三区 | 国产免费久久精品| 一级黄色片免费观看| 久久综合亚洲鲁鲁五月天| 蜜桃视频在线观看免费网址入口| 亚洲AV无码之国产精品| 国产成人精品日本亚洲专区| 3d成人免费动漫在线观看| 亚洲av无码精品网站| 13小箩利洗澡无码视频网站免费| 亚洲色四在线视频观看| 成人无遮挡裸免费视频在线观看 | 亚洲国产av高清无码| xvideos亚洲永久网址|