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

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

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

    創(chuàng)建模式之Singleton——單例模式

    1、簡(jiǎn)介
            作為對(duì)象的創(chuàng)建模式,單例模式確保某個(gè)類(lèi)只有一個(gè)實(shí)例,而且自行實(shí)例化,并向系統(tǒng)提供這個(gè)實(shí)例,這個(gè)類(lèi)稱(chēng)為單例類(lèi)。他有三個(gè)要點(diǎn):
            只能有一個(gè)實(shí)例
            自行創(chuàng)建這個(gè)實(shí)例
            自行向系統(tǒng)提供這個(gè)實(shí)例

    2、使用場(chǎng)景及能解決的問(wèn)題
            當(dāng)你只需要一個(gè)類(lèi)實(shí)例時(shí),Singleton才真正有用;如果類(lèi)擁有幾個(gè)實(shí)例,使用Singleton就不再適用。

        設(shè)計(jì)系統(tǒng)時(shí),通常希望控制對(duì)象的用法,防止用戶(hù)復(fù)制對(duì)象或建立新實(shí)例。例如,你可以使用它創(chuàng)建一個(gè)連接池,每次程序需要往數(shù)據(jù)庫(kù)中寫(xiě)入內(nèi)容時(shí)才創(chuàng)建一個(gè)新連接的做法并不明智;相反,一個(gè)或一組已經(jīng)在池中的連接就可以使用Singleton模式實(shí)例化。

            Singleton模式常常和工廠(chǎng)方法模式一同使用,創(chuàng)建一個(gè)系統(tǒng)級(jí)資源,使用這個(gè)資源的代碼并不知道它的特殊類(lèi)型。抽象窗口工具包(AWT)就是組合使用這兩個(gè)模式的典型例子。在GUI應(yīng)用程序中,對(duì)每個(gè)應(yīng)用程序?qū)嵗阋话阒恍枰粋€(gè)圖形元素的實(shí)例,如打印(Print)對(duì)話(huà)框或OK按鈕。

    3、類(lèi)圖


    4、單例模式的運(yùn)行機(jī)制
            Singleton是一個(gè)無(wú)法實(shí)例化的對(duì)象。這種設(shè)計(jì)模式暗示,在任何時(shí)候,只能由JVM創(chuàng)建一個(gè)Singleton
    (對(duì)象)實(shí)例。如果實(shí)例不存在,你通過(guò)創(chuàng)建類(lèi)的新實(shí)例的方法建立一個(gè)類(lèi)來(lái)執(zhí)行這個(gè)模式;如果存在類(lèi)的一個(gè)實(shí)例,就只會(huì)返回那個(gè)對(duì)象的一個(gè)引用。
        下面看看單例模式的幾種實(shí)現(xiàn)方式:
       
     
        方式1:
        

    public class Singleton {

      
    //注意構(gòu)造方法必須是私有的

          private Singleton(){}


      
    //在自己內(nèi)部定義自己一個(gè)實(shí)例,是不是很奇怪?
      
    //注意這是private 只供內(nèi)部調(diào)用


      private static Singleton instance = new Singleton();

      
    //這里提供了一個(gè)供外部訪(fǎng)問(wèn)本class的靜態(tài)方法,可以直接訪(fǎng)問(wèn)  

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


        方式2:

    public class Singleton 
      
    private static Singleton instance = null;

      
    public static synchronized Singleton getInstance() 
    {

          
    //這個(gè)方法比上面有所改進(jìn),不用每次都進(jìn)行生成對(duì)象,只是第一次     
          
    //使用時(shí)生成實(shí)例!

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





        方式2就是我們說(shuō)的:滯后初始化(Lazy Initialization)。為什么會(huì)有滯后初始化這種實(shí)現(xiàn)方式出現(xiàn)呢?我們可用看到在第一種實(shí)現(xiàn)方式中無(wú)法向單例模式的構(gòu)造方法傳遞參數(shù),而使用滯后初始化的方式,我們可用在調(diào)用getInstance()方法的時(shí)候向方法中傳遞參數(shù)。

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

        “有時(shí)在某些情況下,使用Singleton并不能達(dá)到Singleton的目的,如有多個(gè)Singleton對(duì)象同時(shí)被不同的類(lèi)裝入器裝載;在EJB這樣的分布式系統(tǒng)中使用也要注意這種情況,因?yàn)镋JB是跨服務(wù)器,跨JVM的。” --摘自www.jdon.com-《GoF 23種設(shè)計(jì)模式解析》

        “在多線(xiàn)程環(huán)境下,我們無(wú)法保證一個(gè)方法能夠持續(xù)運(yùn)行到結(jié)束,其他線(xiàn)程的方法才開(kāi)始運(yùn)行。因而可能存在這樣一種情形:兩個(gè)線(xiàn)程幾乎同時(shí)嘗試初始化單例類(lèi)。假設(shè)第一個(gè)方法發(fā)現(xiàn)單例為空,而第二個(gè)方法在此刻開(kāi)始運(yùn)行,它也會(huì)發(fā)現(xiàn)該單例為空。接下來(lái),這兩個(gè)方法都將對(duì)該單例進(jìn)行初始化。”  --摘自《Java設(shè)計(jì)模式》

        
    那么在多線(xiàn)程的環(huán)境下我們?cè)趺锤踩氖褂脝卫J侥兀?br />     
        方式3:
       
     《Java并發(fā)編程》一書(shū)建議使用屬于當(dāng)前類(lèi)的鎖進(jìn)行同步,代碼如下:

    public class Singleton 

        
    private static Singleton instance = null
    ;
       
    //注意這里的static非常重要,如果為對(duì)象變量則因?yàn)榇嬖诙喾菘截惗鸩坏较拗频淖饔?/span>
        private static Object classLock = Singleton.class
         
    public static Singleton getInstance() 
    {
          
    //這個(gè)方法比上面有所改進(jìn),不用每次都進(jìn)行生成對(duì)象,只是第一次使用時(shí)生成實(shí)例

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



        在第一個(gè)線(xiàn)程開(kāi)始滯后初始化的時(shí)候,如果有另一線(xiàn)程也準(zhǔn)備開(kāi)始初始化,這時(shí)候,第二個(gè)線(xiàn)程將停止執(zhí)行,等待獲取對(duì)象classLock的鎖。當(dāng)?shù)诙€(gè)線(xiàn)程獲取這個(gè)鎖并開(kāi)始執(zhí)行初始化的時(shí)候,它會(huì)發(fā)現(xiàn)該單例已不再為空(因?yàn)橹淮嬖谠擃?lèi)的唯有實(shí)例,我們可以使用單個(gè)靜態(tài)鎖)。
       
     
        或者:

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

    }

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

    public static synchronized Singleton getInstance()

    5、使用注意事項(xiàng)
            單例模式類(lèi)不能實(shí)現(xiàn)Clonable接口,以防被克隆而產(chǎn)生多個(gè)實(shí)例
        
     public Object clone() throws 

    CloneNotSupportedException 
    {

             
    throw new
     CloneNotSupportedException();

    }



            單例模式類(lèi)不能實(shí)現(xiàn)Serializable接口,以防被序列化而產(chǎn)生多個(gè)實(shí)例

            根據(jù)不同的執(zhí)行,你的Singleton類(lèi)和它的所有數(shù)據(jù)可能被當(dāng)作垃圾收集。因此,在應(yīng)用程序運(yùn)行時(shí),你必須保證存在一個(gè)Singleton類(lèi)的實(shí)時(shí)引用。

            

    posted on 2008-05-28 16:57 云淡風(fēng)清 閱讀(741) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Design Patterns

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

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(1)

    隨筆分類(lèi)(15)

    隨筆檔案(15)

    收藏夾(1)

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 黄视频在线观看免费| 亚洲免费在线播放| 国产亚洲精AA在线观看SEE| 91在线视频免费观看| youjizz亚洲| 丁香五月亚洲综合深深爱| 30岁的女人韩剧免费观看| 国产成人不卡亚洲精品91| 久久精品夜色国产亚洲av| 成年轻人网站色免费看| 色屁屁在线观看视频免费| 香蕉视频在线观看亚洲| 日韩a级毛片免费视频| 成年人性生活免费视频| 国产精品亚洲精品日韩电影| 国产成人亚洲综合无码精品 | 无码专区一va亚洲v专区在线| 四虎国产精品成人免费久久| 亚洲AV无码一区二区三区牲色| 久久亚洲美女精品国产精品| 九九免费精品视频在这里| 三年片免费高清版| 免费H网站在线观看的| 四虎免费永久在线播放| 亚洲熟妇av一区二区三区漫画| free哆拍拍免费永久视频| 成人免费无码H在线观看不卡| 1000部夫妻午夜免费 | 亚洲欧洲免费视频| 在线成人a毛片免费播放| 亚洲精品自产拍在线观看| 久久精品亚洲AV久久久无码| www在线观看播放免费视频日本| 亚洲第一网站免费视频| 亚洲精品线路一在线观看| 亚洲熟妇av一区| kk4kk免费视频毛片| 国产卡二卡三卡四卡免费网址| 国产黄色一级毛片亚洲黄片大全 | 亚洲剧场午夜在线观看| 无遮挡国产高潮视频免费观看|