一、單例模式定義:
在程序運(yùn)行期間熄赡,一個類有且僅有一個實例對象本谜。
二偎窘、單例模式需要解決的問題:
java創(chuàng)建對象時在棧中保存對象的引用溜在,而真實的對象存在于堆內(nèi)存中掖肋。當(dāng)這個對象
失去所有引用志笼,JVM會在空閑時把篓、或堆內(nèi)存不足時調(diào)用GC進(jìn)行垃圾回收。而有些時
候我們沒有必要針對每一個線程創(chuàng)建一個對象紊浩,此時需要使用單例模式坊谁。例如:編
寫一個類負(fù)責(zé)讀取配置文件滑臊。很顯然配置文件僅僅在類初始化時讀取一次即可雇卷,沒
必要針對每個線程請求生成一個對象重新讀取,這樣做很大程度上消耗了系統(tǒng)性
能。這種情況是使用單例模式的一個典型應(yīng)用場景。有些人在提到單例模式的缺點(diǎn)
時講到:單例模式一般職責(zé)過重,違背了單一職責(zé)原則氧映。其實我認(rèn)為這是一種誤區(qū)
單例模式仍然是一個普通的類脱货,它仍然需要遵守程序設(shè)計原則編寫。職責(zé)過重并非
單例模式的設(shè)計存在缺陷臼疫,而是編程人員沒有遵循設(shè)計原則進(jìn)行編碼烫堤。Spring默認(rèn)
作用域下,每一個Bean都是單例的拔创。是不是可以認(rèn)為富蓄,使用Spring開發(fā)的任何項目
都違背了單一職責(zé)原則呢立倍?任何一種設(shè)計模式都是如此,并非設(shè)計模式本身存在什
么問題变擒,問題在于設(shè)計模式的濫用寝志。
三、單利模式的實現(xiàn)方式:
單例模式典型的實現(xiàn)方式有兩種:餓漢式與懶漢式。還存在很多其他的方式舰攒,其實
都屬于兩種方式的變種。是對這兩種方式做出的優(yōu)化兽叮。我會在接下來的代碼中對這
幾種單 例模式進(jìn)行介紹鹦聪,更多是以代碼中加注釋的方式來解釋每一種設(shè)計模式蒂秘。以
后的文章也會采取這種風(fēng)格
四、餓漢式代碼實現(xiàn):
餓漢式單例模式的特點(diǎn):
基于ClassLoader機(jī)制解決了多線程并發(fā)時的問題规丽,是線程安全的赌莺。不具備懶加載
的特性艘狭。
五、懶漢式代碼實現(xiàn):
經(jīng)過雙重if校驗遵倦、sychronized港谊、volatile關(guān)鍵詞處理后的懶漢式,解決了線程安全燥狰、
訪問阻塞的問題斜筐。
六、靜態(tài)內(nèi)部類實現(xiàn)單例模式:
同樣利用了ClassLoader的機(jī)制解決了線程安全的問題目代,但由于在Singleton類被
被加載時SingletonHolder類沒有被使用榛了,因此具有懶加載的特性煞抬。
七、枚舉:
默認(rèn)情況下枚舉的創(chuàng)建是線程安全的战坤。該方式能夠防止使用反射創(chuàng)建對象途茫。由于枚舉是在初次訪問時才被加載溪食,因此是具有懶加載特性的。該方式寫法簡潔边败。