設(shè)計模式 — 單例模式
1.單例模式的定義
確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例。
2.單例模式的使用場景
確保某個類只有一個對象的場景,避免產(chǎn)生多個對象消耗過多的資源,或者某種類型的對象那個只應(yīng)該有且只有一個,例如,創(chuàng)建一個對象需要消耗的資源過多,如果訪問IO和數(shù)據(jù)庫等資源時,我們可以考慮單例模式。
3.實現(xiàn)單例模式的主要關(guān)鍵點
3.1.構(gòu)造函數(shù)不對外開放,一般為private。
3.2.通過一個靜態(tài)方法或者枚舉返回單例類對象。
3.3.確保單例類的對象有且只有一個,尤其是在多線程下。
3.4.確保單例類對象在反序列化時不會重新構(gòu)建對象。
通過單例類的構(gòu)造函數(shù)私有化,使得客戶端代碼不能通過new的形式手動構(gòu)造單例類的對象,單例類會暴露一個公有靜態(tài)方法。客戶端需要調(diào)用這個靜態(tài)方法獲取到單例類的唯一對象,在獲取這個單例對象的過程中需要確保線程安全,也就是說在多線程環(huán)境下構(gòu)造單例類的對象也是有且只有一個。
4.單例模式的簡單示例
4.1.餓漢式單例
但是在getInstance之前,如果必須調(diào)用某個方法來給它設(shè)置參數(shù),這樣的情況下這種單例就無法使用。
4.2.懶漢式單例
懶漢模式是聲明一個靜態(tài)對象,并且在用戶第一次調(diào)用getSingle時進行初始化。
4.3.雙重鎖實現(xiàn)單例
雙重鎖實現(xiàn)單例模式的優(yōu)點技能在需要時初始化單例又能夠保證線程安全,且單例對象初始化后調(diào)用getSingle不能進行同步鎖。
第一層主要是為了避免不必要的同步,第二層判斷是為了在null情況下創(chuàng)建實例。雙重鎖的優(yōu)點,資源利用率高,第一次執(zhí)行g(shù)etSingle是單例才會
4.4.靜態(tài)內(nèi)部類實現(xiàn)單例
當?shù)谝淮渭虞dSingle類時并不會初始化single,只有在第一次調(diào)用Single的getSingle方法時才會導(dǎo)致single被初始化,因此第一次調(diào)用getSingle方法會導(dǎo)致虛擬機加載SingleHolder類,這種方式不僅能夠確保線程安全也能夠保證單例對象的唯一性,同時也延遲了單例的實例化。
4.5.枚舉單實例
枚舉在Java中與普通類時一樣的,不僅能夠有字段,還能夠有自己的方法,最重要的是默認枚舉實例的創(chuàng)建是線程安全的,并且在任何情況下他都是一個單例。
4.6.推薦使用
推薦使用雙重檢查鎖單例,和靜態(tài)內(nèi)部類單例。請勿轉(zhuǎn)載,攜手千鋒php。