介紹:
單例模式是一種創(chuàng)建型模式。它保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
類圖:

Singleton(單例類):定義一個(gè)getInstance操作,允許客戶訪問它的唯一實(shí)例,getInstance是一個(gè)靜態(tài)方法,主要負(fù)責(zé)創(chuàng)建自己的唯一實(shí)例。
用法:
? 確保某個(gè)類有且只有一個(gè)對(duì)象時(shí)。
個(gè)人理解:
? 創(chuàng)建一個(gè)對(duì)象需要消耗過多資源時(shí)(IO操作、訪問數(shù)據(jù)庫等)
? 工具類、幫助類( 應(yīng)用程序的日志應(yīng)用、接入第三方SDK等)
? 頻繁實(shí)例化然后銷毀的對(duì)象(日志、網(wǎng)絡(luò)訪問等)
例子:
單例模式是最常用的一個(gè)設(shè)計(jì)模式,常見的寫法有幾種:餓漢式、懶漢式、懶漢式同步鎖、雙重校驗(yàn)鎖、靜態(tài)內(nèi)部類的單例模式。
1、餓漢式(線程安全、沒有懶加載)
public class Singleton{
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
特點(diǎn):直接在應(yīng)用加載時(shí)初始化,但會(huì)浪費(fèi)內(nèi)存。
解析:在類初始化時(shí)已經(jīng)初始化實(shí)例,線程安全的。
2、懶漢式(線程不安去,有懶加載)
public class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if(null == instance){
instance = new Singleton();
}
return instance;
}
}
特點(diǎn):單例的初始化操作,延遲到需要的時(shí)候才進(jìn)行,但線程不安全。
解析:在調(diào)用getInstance()方法時(shí)才實(shí)例化,達(dá)到延遲加載的效果。
3、懶漢式同步鎖(線程安全,有懶加載)
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
return instance;
}
}
特點(diǎn):使用同步鎖synchronized保證多線程情況下單例對(duì)象的唯一性,但很多不必要的同步會(huì)影響性能。
解析:synchronized會(huì)造成不必要的同步開銷,很多情況也不需要同步,不推薦使用。
4、雙重校驗(yàn)鎖(線程安全,有懶加載)
public class Singleton {
private static volatile Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
if (instance == null) { //此處避免了不必要的同步
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
特點(diǎn):線程安全,避免了不必要的同步,但高并發(fā)環(huán)境下小概率會(huì)有DCL失效問題。
解析:instance = new Singleton();語句,大概做了3件事情:
(1)、給Singleton的實(shí)例分配內(nèi)存
(2)、調(diào)用Singleton()的構(gòu)造函數(shù)
(3)、將instance對(duì)象指向分配的內(nèi)存空間(instance不是null了)
但由于java編譯器允許處理器亂序執(zhí)行,執(zhí)行順序可能是 (1)-(2)-(3)或者(1)-(3)-(2)。如果是后者情況,切換到另外的線程中,instance已經(jīng)不是null了,線程B直接取走instance,再使用時(shí)就會(huì)出錯(cuò),這就是DCL失效的問題了。
5、靜態(tài)內(nèi)部類的單例模式(線程安全,有懶加載)
public class Singleton{
private Singleton(){}
public static Singleton newInstance(){
return SingletonHolder.instance;
}
//內(nèi)部類,在裝載該內(nèi)部類時(shí)才會(huì)去創(chuàng)建單例對(duì)象
private static class SingletonHolder{
public static Singleton instance = new Singleton();
}
}
特點(diǎn):懶加載的同時(shí)保證線程安全,推薦使用
解析:為什么會(huì)線程安全?類的構(gòu)造器<clinit>()方法在多線程環(huán)境中被正確地加載,同步,如果多個(gè)線程同時(shí)去初始化一個(gè)類,那么只有一個(gè)線程去執(zhí)行這個(gè)類的,其他線程都需要阻塞等待,直到活動(dòng)線程執(zhí)行<clinit>()方法完畢。
總結(jié):
上述幾種做法已經(jīng)滿足了絕大部分的需求,還有一些其它做法可以參考其它資料哈。
另外,單例模式需要注意內(nèi)存泄漏的問題,當(dāng)一個(gè)對(duì)象已經(jīng)不需要再使用本該被回收時(shí),另外一個(gè)正在使用的對(duì)象持有它的引用從而導(dǎo)致它不能被回收,產(chǎn)生了內(nèi)存泄漏。
感謝您的閱讀~
轉(zhuǎn)載請(qǐng)注明出處喔:http://www.itdecent.cn/p/40f848b2af07
推薦閱讀
基礎(chǔ)篇:
設(shè)計(jì)模式前篇之——UML類圖必會(huì)知識(shí)點(diǎn)
設(shè)計(jì)模式前篇之——一起過一下面向?qū)ο蟮母拍?/a>
創(chuàng)建型模式:
簡(jiǎn)易理解設(shè)計(jì)模式之:簡(jiǎn)單工廠模式——來試試接入支付功能
簡(jiǎn)易理解設(shè)計(jì)模式之:工廠方法模式——數(shù)據(jù)存儲(chǔ)例子
簡(jiǎn)易理解設(shè)計(jì)模式之:抽象工廠模式——更換數(shù)據(jù)庫例子
簡(jiǎn)易理解設(shè)計(jì)模式之:建造者模式——學(xué)習(xí)使用“鏈?zhǔn)秸{(diào)用”
簡(jiǎn)易理解設(shè)計(jì)模式之:原型模式——深、淺拷貝的概念
簡(jiǎn)易理解設(shè)計(jì)模式之:?jiǎn)卫J健獑卫J降膸追N常用寫法
結(jié)構(gòu)型模式:
簡(jiǎn)易理解設(shè)計(jì)模式之:適配器模式——Android列表視圖控件設(shè)計(jì)方式
簡(jiǎn)易理解設(shè)計(jì)模式之:橋接模式——穿衣服經(jīng)典案例2
簡(jiǎn)易理解設(shè)計(jì)模式之:組合模式——實(shí)現(xiàn)View中的樹狀結(jié)構(gòu)
簡(jiǎn)易理解設(shè)計(jì)模式之:裝飾模式——穿衣服經(jīng)典案例
簡(jiǎn)易理解設(shè)計(jì)模式之:外觀模式——第三方SDK的幫助類
簡(jiǎn)易理解設(shè)計(jì)模式之:享元模式——五子棋游戲例子
簡(jiǎn)易理解設(shè)計(jì)模式之:代理模式——iOS視圖控件設(shè)計(jì)方式
行為型模式:
簡(jiǎn)易理解設(shè)計(jì)模式之:策略模式——優(yōu)化一下支付功能
簡(jiǎn)易理解設(shè)計(jì)模式之:模板方法模式——Android中的BaseActivity基類
簡(jiǎn)易理解設(shè)計(jì)模式之:觀察者模式——監(jiān)聽與回調(diào)
簡(jiǎn)易理解設(shè)計(jì)模式之:狀態(tài)模式——優(yōu)化登錄操作
簡(jiǎn)易理解設(shè)計(jì)模式之:備忘錄模式——Word文檔的工作原理
簡(jiǎn)易理解設(shè)計(jì)模式之:迭代器模式——遍歷對(duì)象的好幫手
簡(jiǎn)易理解設(shè)計(jì)模式之:命令模式——實(shí)現(xiàn)命令的參數(shù)化配置
簡(jiǎn)易理解設(shè)計(jì)模式之:責(zé)任鏈模式——OA中請(qǐng)假流程示例
簡(jiǎn)易理解設(shè)計(jì)模式之:中介者模式——多人聊天室例子
簡(jiǎn)易理解設(shè)計(jì)模式之:解釋器模式——語言和文法
簡(jiǎn)易理解設(shè)計(jì)模式之:訪問者模式——員工考核例子