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

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章分類

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜


          一 基本概念
          單例模式是一種為類 提供唯一實(shí)例的設(shè)計(jì)模式。單例模式的目的是為了控制對(duì)象的創(chuàng)建,它可以限制創(chuàng)建的數(shù)目為一,但在情況改變的時(shí)候,也允許靈活地創(chuàng)建更多的對(duì)象。因?yàn)橹挥幸粋€(gè)實(shí)例,所以也只有一套實(shí)例的類變量的拷貝,這很像 static 變量。

          在 JAVA 中,單例模式不應(yīng)該被當(dāng)作一種實(shí)現(xiàn)全局變量的方法。更多的,如同工廠模式,單例模式允許你通過(guò) 確認(rèn)某些先決條件是否滿足 或者 以 lazily 方式按需創(chuàng)建的方式 來(lái)封裝和控制創(chuàng)建過(guò)程。

          二 編程實(shí)現(xiàn)
          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;
              }


          }

          由于只有一個(gè)私有構(gòu)造器,所以單例類是無(wú)法被集成的。基于這一點(diǎn),單例模式并不是一個(gè)面向?qū)ο竽J剑瑑H僅是一個(gè)基于對(duì)象的模式。

          3 饑餓模式基本沒(méi)有問(wèn)題,懶漢模式則容易出現(xiàn)一些錯(cuò)誤的編程方法
          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();
                      }

                  }

              }

          }

          為了避免每次調(diào)用 getInstance方法是抓取同步鎖的消耗,有人發(fā)明了 Double-checked locking 。但不要使用,因?yàn)檫@樣的代碼將無(wú)法在編譯器優(yōu)化和多處理器共享內(nèi)存的情況下工作。若想詳細(xì)了解,附錄中有對(duì)此做詳細(xì)描述的鏈接。

          三 總結(jié)

          1 單例模式不應(yīng)被濫用,比如不能為了得到一個(gè)全局變量而創(chuàng)建單例,單例是用于控制對(duì)象的創(chuàng)建過(guò)程的。只有真正的目的是控制對(duì)象創(chuàng)建的過(guò)程或數(shù)量時(shí),才能考慮使用單例。在大部分情況下,單例模式是有代替方案的。比如經(jīng)典的數(shù)據(jù)庫(kù)連接類被以單例實(shí)現(xiàn),其實(shí)可以以對(duì)象池模式實(shí)現(xiàn)。

          2 使用單例模式,盡量使用饑餓模式 ,只有你能預(yù)測(cè)這個(gè)類一定會(huì)被創(chuàng)建,那么就可以使用饑餓模式。如果,一定需要推遲對(duì)象的創(chuàng)建時(shí)間。那么不要使用 Double-checked locking 之類的方法的來(lái)提高效率,這將得不償失。

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

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 吐鲁番市| 根河市| 女性| 宜城市| 永年县| 蓬溪县| 旬邑县| 绵竹市| 资源县| 夏邑县| 吉林省| 定西市| 宜黄县| 镇宁| 盐源县| 玉环县| 敦煌市| 会同县| 略阳县| 瑞昌市| 灵山县| 南投市| 庆云县| 白朗县| 都兰县| 峨山| 巴林左旗| 龙门县| 万盛区| 大新县| 枝江市| 黔江区| 安阳市| 安陆市| 南平市| 龙岩市| 英吉沙县| 永寿县| 孟津县| 富裕县| 遵义县|