<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

    主站蜘蛛池模板: 午夜爽爽爽男女免费观看影院| 亚洲人成777在线播放| 亚洲a无码综合a国产av中文| 最近最新MV在线观看免费高清| 亚洲区精品久久一区二区三区| 在线观看免费av网站| 亚洲理论精品午夜电影| 色片在线免费观看| 亚洲熟妇AV日韩熟妇在线| 成人黄动漫画免费网站视频| 亚洲综合av一区二区三区不卡 | 亚洲精品国产综合久久久久紧| 999国内精品永久免费观看| 亚洲av午夜精品无码专区| 香蕉97超级碰碰碰免费公| 亚洲日韩国产欧美一区二区三区| 狠狠久久永久免费观看| 污视频网站免费在线观看| 国产亚洲成av片在线观看| 亚洲成年人免费网站| 在线综合亚洲中文精品| 国产在线观看免费视频播放器 | 久久免费动漫品精老司机| 亚洲黄色免费网址| 女人18毛片a级毛片免费视频| 污污视频免费观看网站| 久久久久亚洲av无码尤物| 在线观看免费人成视频色| 国产亚洲精品仙踪林在线播放| 伊人久久亚洲综合| 亚洲大片免费观看| 香蕉视频在线观看免费| 久久精品7亚洲午夜a| 岛国av无码免费无禁网站| yellow免费网站| 亚洲国产av一区二区三区丶| 少妇亚洲免费精品| 97人妻无码一区二区精品免费| 特级毛片A级毛片免费播放| 久久亚洲国产精品一区二区| 最新仑乱免费视频|