隨筆 - 35  文章 - 21  trackbacks - 0
          <2010年4月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章分類

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜


          一 基本概念
          單例模式是一種為類 提供唯一實例的設計模式。單例模式的目的是為了控制對象的創建,它可以限制創建的數目為一,但在情況改變的時候,也允許靈活地創建更多的對象。因為只有一個實例,所以也只有一套實例的類變量的拷貝,這很像 static 變量。

          在 JAVA 中,單例模式不應該被當作一種實現全局變量的方法。更多的,如同工廠模式,單例模式允許你通過 確認某些先決條件是否滿足 或者 以 lazily 方式按需創建的方式 來封裝和控制創建過程。

          二 編程實現
          1 饑餓模式 Eager Singleton

          public class MySingleton {
              
          private static MySingleton fInstance = new MySingleton();
              
              
          private MySingleton(){
                  
          // Construct object 
              }


              
          public static MySingleton getInstance(){
                  reutnr fInstance;
              }


          }

          2 懶漢模式 Lazy Singleton

          public class MySingleton {
              
          private static MySingleton fInstance;
              
              
          private MySingleton(){
                  
          // construct object
              }

              
              
          public static synchronized MySingleton getInstance(){
                  
          if (fInstance == null){
                      fInstance 
          = new MySingleton();
                  }

                  
          return fInstance;
              }


          }

          由于只有一個私有構造器,所以單例類是無法被集成的。基于這一點,單例模式并不是一個面向對象模式,僅僅是一個基于對象的模式。

          3 饑餓模式基本沒有問題,懶漢模式則容易出現一些錯誤的編程方法
          1)
          // error, no synchronization on method 
          public static MySingleton getInstance() 
           
          if (fInstance==null
               fInstance 
          = new MySingleton(); 
           }
           

           
          return fInstance; 
          }

          2)
          // Also an error, synchronization does not prevent 
          // two calls of constructor. 
          public static MySingleton getInstance() 
           
          if (fInstance==null
             
          synchronized (MySingleton.class
                fInstance 
          = new MySingleton(); 
             }
           
           }
           
           
          return fInstance; 
          }
           

          3) Double-checked locking 不要使用

          public static MySingleton getInstance(){
              
          if (fInstance == null ){
                  
          synchronized (MySingleton.class{
                      
          if(fInstance == null){
                          fInstance 
          = new MySingleton();
                      }

                  }

              }

          }

          為了避免每次調用 getInstance方法是抓取同步鎖的消耗,有人發明了 Double-checked locking 。但不要使用,因為這樣的代碼將無法在編譯器優化和多處理器共享內存的情況下工作。若想詳細了解,附錄中有對此做詳細描述的鏈接。

          三 總結

          1 單例模式不應被濫用,比如不能為了得到一個全局變量而創建單例,單例是用于控制對象的創建過程的。只有真正的目的是控制對象創建的過程或數量時,才能考慮使用單例。在大部分情況下,單例模式是有代替方案的。比如經典的數據庫連接類被以單例實現,其實可以以對象池模式實現。

          2 使用單例模式,盡量使用饑餓模式 ,只有你能預測這個類一定會被創建,那么就可以使用饑餓模式。如果,一定需要推遲對象的創建時間。那么不要使用 Double-checked locking 之類的方法的來提高效率,這將得不償失。

          [1] DoubleCheckedLocking
          http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
          posted on 2010-04-30 21:04 lincode 閱讀(218) 評論(0)  編輯  收藏 所屬分類: Design pattern

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


          網站導航:
           
          主站蜘蛛池模板: 临沧市| 肥乡县| 米脂县| 仪陇县| 康平县| 彭泽县| 济源市| 南靖县| 涿州市| 巍山| 甘孜县| 许昌县| 安平县| 孟连| 天台县| 大兴区| 梁河县| 陈巴尔虎旗| 肥乡县| 遂平县| 西城区| 漯河市| 邛崃市| 达孜县| 方正县| 肥东县| 柘城县| 平武县| 淳化县| 丰宁| 闻喜县| 武乡县| 贵德县| 鄂温| 武胜县| 射洪县| 荆门市| 绥芬河市| 高密市| 奉化市| 阳城县|