posts - 2,  comments - 0,  trackbacks - 0
              《設計模式》中對Singleton模式的定義為:保證一個類僅有一個實例,并提供一個可以訪問它的全局訪問點。

              Singleton模式的工作原理如下:
          1. 用一個方法來實例化所需對象。為了保證該方法是唯一能實例化此類型對象的方法,我們將這個類的構造函數定義為保護的或者私有的。
          2. 調用這個方法時,先要檢查對象是否已經實例化了。如果已被實例化,那么該方法僅返回對該對象的引用;如果尚未實例化,該方法將實例化對象并返回對此新實例的一個引用。
             根據上述原理,我們可以得到Singleton模式的本質在于所有使用所需對象的其他對象都使用同一個實例。Singleton模式的意圖使我們只對所需對象實例化一次,無需用戶再關心所需對象是否存在,即讓所需對象自己負責只實例化一次。
             單例模式一般代碼如下:

           1 public class Singleton {
           2     static private Singleton instance = new Singleton();
           3         
           4     private Singleton(){}
           5         
           6     public static Singleton getInstance(){
           7             return instance;
           8     }
           9 }
              當ClassLoader加載類后Singleton的實例會在第一時間內創建,因此對于開銷比較大的單體更通常的做法是將實例化推遲到使用它的時候,即惰性加載,代碼如下:
           1 public class Singleton {
           2     static private Singleton instance = null;
           3         
           4     private Singleton(){}
           5         
           6     public static Singleton getInstance(){
           7          if(instance == null) instance =new Singleton();
           8         return instance;
           9     }
          10 }

              這是在單線程中的情況,如果我們的代碼要在多線程中運行呢?
              咋看起來,只需同步化對Singleton對象是否已創建進行檢查操作即可。但性能上來說不不劃算,因為所有線程都必須等待關于對象是否存在的檢查。因此可能想到的是如下解決方法:
          1 if(instance == null) {
          2     synchronized(Singleton.class){
          3         instance = new Singleton();
          4      }
          5 }
               但仍有可能兩個調用都滿足null的檢查條件,然后再嘗試同步化,最后還是可能會創建兩個Singleton對象。解決辦法是在同步檢查后,再次檢查實例是否已創建。
          1 if(instance == null) {
          2         synchronized(Singleton.class){
          3                if(instance == null) instance = new Singleton();
          4          }
          5 }
               這種方法被稱為DCL(Double-Checked Locking模式)。但是我們很快發現,這種方法在C++中適用,但對Java不適用,原因在于Java編譯器本身的優化工作會在構造方法實例化對象之前從構造方法返回指向該對象的引用。印在在Singleton對象真正完全構造之前,dosyn就可能完成了。那怎么辦呢?
               我們可以利用類裝載程序來解決這個問題。
          1 public class Singleton {
          2      private static class Instance{
          3             static final Singleton instance = new Singleton();
          4             public static Singleton getInstance(){
          5                 return  Instance.instance;
          6             }
          7      }
          8 }
             這個方案之所以奏效,是因為內部類(Instance)只被裝載一次,所以只會創建一個Singleton對象。


          參考:
          1.《設計模式解析》Singleton模式和DCL模式
          2.探索設計模式之六——單例模式
          posted on 2012-07-27 01:04 hqjma 閱讀(117) 評論(0)  編輯  收藏 所屬分類: Design Pattern

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


          網站導航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 赣州市| 汽车| 咸阳市| 高碑店市| 开封县| 雷波县| 巴林右旗| 亚东县| 梨树县| 东海县| 会同县| 大足县| 马尔康县| 白河县| 柏乡县| 东海县| 公主岭市| 北安市| 尼玛县| 团风县| 青浦区| 栾城县| 噶尔县| 广昌县| 阿鲁科尔沁旗| 仙游县| 卓尼县| 商水县| 盐山县| 开封市| 宜川县| 乾安县| 文山县| 兴城市| 虞城县| 白朗县| 夏河县| 宜君县| 昆明市| 永德县| 蓝山县|