最近研究項(xiàng)目底層使用依賴組件的源碼,發(fā)現(xiàn)了單例模式的正確使用姿勢(shì),同時(shí)重溫《Java程序性能優(yōu)化》章節(jié)的講解,兩相印證對(duì)單例設(shè)計(jì)模式算是整明白了。
單例模式:設(shè)計(jì)目的是對(duì)于頻繁使用的對(duì)象,單例可以節(jié)省創(chuàng)建對(duì)象花費(fèi)的時(shí)間。
常說(shuō)的餓漢式,懶漢式,只是形象化的比喻,方便去理解設(shè)計(jì)模式,結(jié)果本末倒置,只記住了名詞,忘記了名詞代表的背后含義。
通過(guò)兩兩比較,來(lái)剖析單例不同模式的優(yōu)缺點(diǎn):
懶漢式比較于餓漢式核心的意義在于引入懶加載,在需要使用的時(shí)候才創(chuàng)建對(duì)象,而不是系統(tǒng)啟動(dòng)的時(shí)候就創(chuàng)建
優(yōu)點(diǎn)1:避免系統(tǒng)啟動(dòng)時(shí)有額外的負(fù)載
優(yōu)點(diǎn)2:?jiǎn)卫惪赡苡衅渌姆椒?,餓漢式的方式會(huì)導(dǎo)致只要使用這個(gè)單例類的地方都會(huì)初始化這個(gè)單例變量(這點(diǎn)往往被忽視,導(dǎo)致無(wú)法認(rèn)識(shí)懶加載的優(yōu)點(diǎn))


在使用懶漢式的時(shí)候,有人會(huì)說(shuō)已經(jīng)添加了volatile關(guān)鍵字,為什么還需要添加synchronized關(guān)鍵字,其實(shí)是對(duì)于volatile關(guān)鍵字理解不正確導(dǎo)致的,volatile并不能保證多線程的安全性,只能保證修飾變量的可見(jiàn)性和有序性,所以在多線程場(chǎng)景下,如果不加synchronized關(guān)鍵字,線程1正在創(chuàng)建對(duì)象,線程2判斷instance為null,也新建了一個(gè)單例對(duì)象,就有多個(gè)實(shí)例被創(chuàng)建,到了這里,出現(xiàn)了一個(gè)我一直糾結(jié)的問(wèn)題,多個(gè)實(shí)例都一樣,能咋地,也沒(méi)啥影響哇,直到看到了舉例:win系統(tǒng)只有一個(gè)回收站,為什么,因?yàn)槿绻谝粋€(gè)窗口中刪除的文件在另一窗口還存在,有歧義,全局唯一在這個(gè)例子中體現(xiàn)的很明確,解釋的很合理,說(shuō)服了我。
但是為了使用懶加載而引入的同步關(guān)鍵字,又帶來(lái)了另一個(gè)缺點(diǎn),系統(tǒng)性能的損耗,所以引出了工作中項(xiàng)目使用的更好的創(chuàng)建方式,使用靜態(tài)內(nèi)部類:

靜態(tài)內(nèi)部類的加載時(shí)機(jī):
外部類加載的時(shí)候,內(nèi)部類不會(huì)被初始化
調(diào)用靜態(tài)內(nèi)部類的變量時(shí),外部類也不會(huì)加載,避免了引入同步關(guān)鍵字,具備餓漢式和懶漢式各自的優(yōu)點(diǎn),真的很優(yōu)秀。