設(shè)計(jì)模式-由淺到深的單例模式-創(chuàng)新互聯(lián)

前言:說起單例模式,可能大家都熟悉,可以說是設(shè)計(jì)模式中出現(xiàn)頻率最高的一個,為了徹底弄清單例,在這里我將說明何為單例,單例模式的演變,已經(jīng)和靜態(tài)類之間的區(qū)別等。

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的資溪網(wǎng)站設(shè)計(jì)、移動媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

1:概念

何為單例,就是在一個應(yīng)用程序中只能有一個實(shí)例,就是保證對象只能被new一次。

2:懶漢模式

懶漢我覺得這個名字很形象,就是很懶,所以別的對象加載,它就不加載,你調(diào)用我的時(shí)候我在加載。比喻hibernate中也有懶模式。ok我們開始吧

2.1:非線程安全

一天小明去面試,面試官說,你給我寫個單例模式,小明一想這實(shí)在太簡單了不暇思索很快寫出來了如下的單例模式

設(shè)計(jì)模式-由淺到深的單例模式

 1 public class Singleton { 2     private static Singleton singleton; 3     public static Singleton getSingleton() 4     { 5         if(singleton==null) 6         { 7             singleton=new Singleton(); 8         } 9         return singleton;10     }11 }

設(shè)計(jì)模式-由淺到深的單例模式

然后面試官一看說:你這在高并發(fā)的時(shí)候有可能會產(chǎn)生多個singleton實(shí)例,小明一想怎么會呢,面試官解釋說,如果有2個線程T1,T2同時(shí)執(zhí)行,當(dāng)T1執(zhí)行到第6行的時(shí)候,時(shí)間片段到,系統(tǒng)開始讓T2執(zhí)行,執(zhí)行到第9行,然后T1又開始執(zhí)行,因?yàn)門1已經(jīng)做過判斷此時(shí)并不知道singleton已經(jīng)被實(shí)例化,所以singleton此時(shí)再次被實(shí)例化,這樣你系統(tǒng)就有2個singleton對象,那還是單例嗎,小明恍然大悟,這個我能解決,馬上又寫出下面這個

2.2:線程安全

設(shè)計(jì)模式-由淺到深的單例模式

 1 public class Singleton { 2     private static Singleton singleton; 3      4     public synchronized static Singleton getSingleton() 5     { 6         if(singleton==null) 7             { 8                 singleton=new Singleton(); 9             }10             return singleton;11     }

設(shè)計(jì)模式-由淺到深的單例模式

面試官一看,加上了線程同步,這個時(shí)候確實(shí)能保證線程安全問題,但是又提出了疑問,如果現(xiàn)在singleton已經(jīng)被實(shí)例化了,如果10個線程同時(shí)訪問,每次都要等待那么勢必造成性能極大的消耗,你有沒有別的方案解決問題,小明思考一分鐘又寫下了下面一段代碼

2.3:雙重校驗(yàn)

設(shè)計(jì)模式-由淺到深的單例模式

 1 public class Singleton { 2     private static Singleton singleton; 3      4     public  static Singleton getSingleton() 5     { 6         if(singleton==null) 7         { 8             synchronized (Singleton.class) { 9                 if(singleton==null)10                 {11                     singleton=new Singleton();12                 }13             }14         }15         return singleton;16     }

設(shè)計(jì)模式-由淺到深的單例模式

面試官一看,果真在上面一段代碼的基礎(chǔ)上提升了不少性能,減少了不必要的等待,但是仔細(xì)一看說你這代碼有點(diǎn)問題,并不能保證線程的安全,小明說怎么說呢,然后面試官解釋說:如果有T1,T2兩個線程,T1線程運(yùn)行第六行發(fā)現(xiàn)singleton==null,就進(jìn)入第8行,開始對singleton進(jìn)行實(shí)例化,因?yàn)閷?shí)例化中分為三步,第一步為對象開辟內(nèi)存空間,第二步為對象初始化,第三步是把這個內(nèi)存地址賦給singleton,但是因?yàn)閖ava的內(nèi)存模式允許無序?qū)懭?,這樣一來會導(dǎo)致第二步和第三步位置調(diào)換,那么這樣一來就壞了,如果先允許第一步和第三步了,但是此時(shí)并沒有對對象進(jìn)行初始化,恰恰在此時(shí)T2進(jìn)入了第6行,經(jīng)過判斷singleton不為null,那么就會返回一個沒有被初始化的對象。小明聽了覺得對啊,他說我把內(nèi)存模式改為不允許無序?qū)懭氩痪托辛藛幔谑蔷桶汛a修改為

設(shè)計(jì)模式-由淺到深的單例模式

 1 public class Singleton { 2     private volatile static Singleton singleton;//表示有序?qū)懭?nbsp;3      4     public  static Singleton getSingleton() 5     { 6         if(singleton==null) 7         { 8             synchronized (Singleton.class) { 9                 if(singleton==null)10                 {11                     singleton=new Singleton();12                 }13             }14         }15         return singleton;16     }

設(shè)計(jì)模式-由淺到深的單例模式

注釋1:對象實(shí)例化三步我這里做一個比喻,某個公司給員工分配一間寢室(指的就是在堆中開辟了空間)然后呢給房子進(jìn)行一些標(biāo)配比喻分個空調(diào)、洗衣機(jī)什么的(對象初始化),在然后呢把鑰匙給到員工手里(對象進(jìn)行賦值)。

3:餓漢模式

面試官又問你知道餓漢模式怎么寫的嗎,小明一聽:哦餓漢,不就是很著急自己馬上進(jìn)行實(shí)例化,生怕自己無法實(shí)例化嗎,這個簡單馬上寫了一個餓漢

設(shè)計(jì)模式-由淺到深的單例模式

public class Singleton {    
    private static Singleton singleton=new Singleton();    public  static Singleton getSingleton()
    {        return singleton;
    }
}

設(shè)計(jì)模式-由淺到深的單例模式

面試官一看確實(shí)不錯。

4:內(nèi)部類模式

小明一看上面的模式,自己突發(fā)奇想,餓漢模式著急創(chuàng)建對象,在加載時(shí)候消耗性能,而懶漢模式又存在線程安全問題(優(yōu)化后沒有了)能不能結(jié)合一下呢,突然告訴面試官我還有一個比較好的方式來實(shí)現(xiàn),然后他寫了下面代碼

設(shè)計(jì)模式-由淺到深的單例模式

1 public class Singleton {    
2     private static class SingletonManager{3         private final static  Singleton SINGLETON=new Singleton();4     }5     public final static Singleton getSingleton()6     {7         return SingletonManager.SINGLETON;8     }

設(shè)計(jì)模式-由淺到深的單例模式

面試官一看,不錯不錯,既保證了懶加載,同時(shí)也保證了線程安全問題。

5:使用場景

面試官又問小明,那么你知道使用場景嗎,小明想了想說,既然在應(yīng)用程序中只有一個單例,那么勢必是用于共享資源,比喻數(shù)據(jù)庫連接池,線程池等都可以用單例模式。

6:單例模式和靜態(tài)類區(qū)別

面試官繼續(xù)問:靜態(tài)類同樣也是產(chǎn)生一個對象,和單例具有高度相似你知道他們區(qū)別嗎,小明回答說

1:面向?qū)ο笾杏腥筇匦岳^承,封裝和多態(tài),但是靜態(tài)類是不可以繼承的,所以從oo角度來說靜態(tài)類并不符合面向?qū)ο螅麄兊念愂遣豢梢员桓采w,所以靈活性要比單例差的多

2:由于靜態(tài)類的特殊他在編譯器已經(jīng)進(jìn)行實(shí)例化了并不能提供懶加載模式

3:對于項(xiàng)目中如果進(jìn)行單元測試,由于方法不能覆蓋同樣為測試帶來了困難

4:由于靜態(tài)類在編譯器已經(jīng)都被實(shí)例化,所以要比單例性能要快,如果只需要執(zhí)行一些靜態(tài)方法這個時(shí)候可以采用靜態(tài)類

7:總結(jié)

單例模式看似簡單,其實(shí)用起來還要考慮到很多問題,現(xiàn)在我把這個過程基本總結(jié)了,當(dāng)然可能還有不足之處,歡迎指正。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)頁標(biāo)題:設(shè)計(jì)模式-由淺到深的單例模式-創(chuàng)新互聯(lián)
瀏覽路徑:http://bm7419.com/article0/ddpsoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、網(wǎng)站設(shè)計(jì)公司關(guān)鍵詞優(yōu)化、網(wǎng)站收錄移動網(wǎng)站建設(shè)、做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)