單例模式適用場景為 1.需要頻繁實例化然后銷毀的對象最冰。 2.創(chuàng)建對象時耗時過多或者耗資源過多瘦棋,但又經(jīng)常用到的對象。 3.有狀態(tài)的工具類對象锌奴。 4.頻繁訪問數(shù)據(jù)庫或文件的對象兽狭。?
通常單例模式與靜態(tài)類會拿來比較,一般如果想要利用唯一的實例保存系統(tǒng)的狀態(tài)鹿蜀,這時應(yīng)該選用單例模式箕慧,如果僅僅是想不自己創(chuàng)建類的實例就可以調(diào)用到某些方法來完成一定的操作,那完全沒必要也不應(yīng)該使用單例模式茴恰。
單例模式的實現(xiàn)有多種方式颠焦,但是考慮到線程安全與執(zhí)行效率一般生產(chǎn)環(huán)境下會采用一下模式:
? ? ? ? 關(guān)于volatile關(guān)鍵字這里做簡單介紹。在并發(fā)編程中常常關(guān)注:原子性往枣、可見性伐庭、有序性三個問題粉渠,volatile和synchronized關(guān)鍵字也是經(jīng)常被提到的兩個關(guān)鍵字。volatile關(guān)鍵字可以保證可見性和有序性(防止指令重排)圾另,而synchronized可以保證原子性霸株。
? ? ? ? 1、使用volatile 修飾實例變量集乔,是為了避免多線程情況下去件,會出現(xiàn)A線程執(zhí)行初始化,但可能因為構(gòu)造函數(shù)里面的操作太多了扰路,所以A線程的singleton實例還沒有造出來尤溜,但已經(jīng)被賦值了。而B線程這時過來了汗唱,錯以為 singleton? 已經(jīng)被實例化出來宫莱,一用才發(fā)現(xiàn) singleton? 尚未被初始化。
? ? ? ? 2哩罪、兩次判斷singleton為空是因為并把synchronized操作放在第一次判空后是因為授霸,同步操作執(zhí)行效率低,如果singleton不為空就避免了同步操作识椰。第二次判空是為了防止在構(gòu)造同步鎖的同時另一個線程已經(jīng)實例化了singleton绝葡。