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

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

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

    創建模式之Singleton——單例模式

    1、簡介
            作為對象的創建模式,單例模式確保某個類只有一個實例,而且自行實例化,并向系統提供這個實例,這個類稱為單例類。他有三個要點:
            只能有一個實例
            自行創建這個實例
            自行向系統提供這個實例

    2、使用場景及能解決的問題
            當你只需要一個類實例時,Singleton才真正有用;如果類擁有幾個實例,使用Singleton就不再適用。

        設計系統時,通常希望控制對象的用法,防止用戶復制對象或建立新實例。例如,你可以使用它創建一個連接池,每次程序需要往數據庫中寫入內容時才創建一個新連接的做法并不明智;相反,一個或一組已經在池中的連接就可以使用Singleton模式實例化。

            Singleton模式常常和工廠方法模式一同使用,創建一個系統級資源,使用這個資源的代碼并不知道它的特殊類型。抽象窗口工具包(AWT)就是組合使用這兩個模式的典型例子。在GUI應用程序中,對每個應用程序實例,你一般只需要一個圖形元素的實例,如打印(Print)對話框或OK按鈕。

    3、類圖


    4、單例模式的運行機制
            Singleton是一個無法實例化的對象。這種設計模式暗示,在任何時候,只能由JVM創建一個Singleton
    (對象)實例。如果實例不存在,你通過創建類的新實例的方法建立一個類來執行這個模式;如果存在類的一個實例,就只會返回那個對象的一個引用。
        下面看看單例模式的幾種實現方式:
       
     
        方式1:
        

    public class Singleton {

      
    //注意構造方法必須是私有的

          private Singleton(){}


      
    //在自己內部定義自己一個實例,是不是很奇怪?
      
    //注意這是private 只供內部調用


      private static Singleton instance = new Singleton();

      
    //這里提供了一個供外部訪問本class的靜態方法,可以直接訪問  

      public static Singleton getInstance() 
    {
        
    return instance;   
       }
     
    }
     


        方式2:

    public class Singleton 
      
    private static Singleton instance = null;

      
    public static synchronized Singleton getInstance() 
    {

          
    //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次     
          
    //使用時生成實例!

          if (instance==null)
            instance=
    new Singleton();
                
    return
     instance;
          }
     
           }





        方式2就是我們說的:滯后初始化(Lazy Initialization)。為什么會有滯后初始化這種實現方式出現呢?我們可用看到在第一種實現方式中無法向單例模式的構造方法傳遞參數,而使用滯后初始化的方式,我們可用在調用getInstance()方法的時候向方法中傳遞參數。

    凡事有好處必然有壞處,滯后初始化的一個弊病就是在多線程或分布式的環境下有可能出現混亂:

        “有時在某些情況下,使用Singleton并不能達到Singleton的目的,如有多個Singleton對象同時被不同的類裝入器裝載;在EJB這樣的分布式系統中使用也要注意這種情況,因為EJB是跨服務器,跨JVM的。” --摘自www.jdon.com-《GoF 23種設計模式解析》

        “在多線程環境下,我們無法保證一個方法能夠持續運行到結束,其他線程的方法才開始運行。因而可能存在這樣一種情形:兩個線程幾乎同時嘗試初始化單例類。假設第一個方法發現單例為空,而第二個方法在此刻開始運行,它也會發現該單例為空。接下來,這兩個方法都將對該單例進行初始化。”  --摘自《Java設計模式》

        
    那么在多線程的環境下我們怎么更安全的使用單例模式呢?
      
      
        方式3:
       
     《Java并發編程》一書建議使用屬于當前類的鎖進行同步,代碼如下:

    public class Singleton 

        
    private static Singleton instance = null
    ;
       
    //注意這里的static非常重要,如果為對象變量則因為存在多份拷貝而起不到限制的作用

        private static Object classLock = Singleton.class
         
    public static Singleton getInstance() 
    {
          
    //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次使用時生成實例

              synchronized(classLock){
                  
    if (instance==null
    )
              instance=
    new
     Singleton();
                  
    return
     instance;
              }
     
              }
          
         }



        在第一個線程開始滯后初始化的時候,如果有另一線程也準備開始初始化,這時候,第二個線程將停止執行,等待獲取對象classLock的鎖。當第二個線程獲取這個鎖并開始執行初始化的時候,它會發現該單例已不再為空(因為只存在該類的唯有實例,我們可以使用單個靜態鎖)。
       
     
        或者:

    public class Singleton
    {
       
    private Singleton() {}
      
       
    private static class
     SingletonHolder
       
    {
        
    private final static Singleton INSTANCE = new
     Singleton();
       }
      
       
    public static
     Singleton getInstance()
       
    {
        
    return
     SingletonHolder.INSTANCE;
       }

    }

        另一個解決辦法是在getInstance()方法聲明中添加synchronized關鍵字: 

    public static synchronized Singleton getInstance()

    5、使用注意事項
            單例模式類不能實現Clonable接口,以防被克隆而產生多個實例
        
     public Object clone() throws 

    CloneNotSupportedException 
    {

             
    throw new
     CloneNotSupportedException();

    }



            單例模式類不能實現Serializable接口,以防被序列化而產生多個實例

            根據不同的執行,你的Singleton類和它的所有數據可能被當作垃圾收集。因此,在應用程序運行時,你必須保證存在一個Singleton類的實時引用。

            

    posted on 2008-05-28 16:57 云淡風清 閱讀(741) 評論(0)  編輯  收藏 所屬分類: Design Patterns

    <2008年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(1)

    隨筆分類(15)

    隨筆檔案(15)

    收藏夾(1)

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品乱码久久久久久中文字幕 | 亚洲日韩亚洲另类激情文学| a级成人免费毛片完整版| 国产中文字幕免费| 亚洲av成人一区二区三区在线播放 | 亚洲AV无码国产精品麻豆天美 | 亚洲一区二区三区免费| 免费国产草莓视频在线观看黄| 国产一区二区三区免费在线观看| 亚洲欧洲日产国码久在线| 啦啦啦手机完整免费高清观看| 亚洲最大中文字幕无码网站 | 亚洲 暴爽 AV人人爽日日碰| 无码国产精品一区二区免费I6| 亚洲久悠悠色悠在线播放| 成年轻人网站色免费看| 亚洲AV无码一区二区乱子仑 | 免费观看国产小粉嫩喷水| 色爽黄1000部免费软件下载| 久久久久亚洲AV成人网人人网站| 99久久免费国产精精品| 亚洲午夜精品一区二区| 91在线视频免费看| 国产成人精品亚洲一区| 亚洲国产精品无码久久久蜜芽| 精品熟女少妇av免费久久| 亚洲中文字幕乱码AV波多JI| 国产免费资源高清小视频在线观看| 亚洲一级片免费看| 亚洲狠狠综合久久| 精品久久久久久久久免费影院| 亚洲av综合av一区二区三区| 亚洲无码日韩精品第一页| 亚洲精品免费在线| 亚洲av日韩av永久在线观看| 亚洲精品无码久久毛片| 99视频在线精品免费| 精品久久久久久久久亚洲偷窥女厕| 亚洲无线码在线一区观看| 99精品国产免费久久久久久下载| 成人a毛片视频免费看|