一 基本概念
單例模式是一種為類 提供唯一實(shí)例的設(shè)計(jì)模式。單例模式的目的是為了控制對(duì)象的創(chuàng)建,它可以限制創(chuàng)建的數(shù)目為一,但在情況改變的時(shí)候,也允許靈活地創(chuàng)建更多的對(duì)象。因?yàn)橹挥幸粋€(gè)實(shí)例,所以也只有一套實(shí)例的類變量的拷貝,這很像 static 變量。
在 JAVA 中,單例模式不應(yīng)該被當(dāng)作一種實(shí)現(xiàn)全局變量的方法。更多的,如同工廠模式,單例模式允許你通過(guò) 確認(rèn)某些先決條件是否滿足 或者 以 lazily 方式按需創(chuàng)建的方式 來(lái)封裝和控制創(chuàng)建過(guò)程。
二 編程實(shí)現(xiàn)
1 饑餓模式 Eager Singleton












2 懶漢模式 Lazy Singleton















由于只有一個(gè)私有構(gòu)造器,所以單例類是無(wú)法被集成的。基于這一點(diǎn),單例模式并不是一個(gè)面向?qū)ο竽J剑瑑H僅是一個(gè)基于對(duì)象的模式。
3 饑餓模式基本沒(méi)有問(wèn)題,懶漢模式則容易出現(xiàn)一些錯(cuò)誤的編程方法
1)
// error, no synchronization on method
public static MySingleton getInstance() {
if (fInstance==null) {
fInstance = new MySingleton();
}

return fInstance;
}
2)










3) Double-checked locking 不要使用









為了避免每次調(diào)用 getInstance方法是抓取同步鎖的消耗,有人發(fā)明了 Double-checked locking 。但不要使用,因?yàn)檫@樣的代碼將無(wú)法在編譯器優(yōu)化和多處理器共享內(nèi)存的情況下工作。若想詳細(xì)了解,附錄中有對(duì)此做詳細(xì)描述的鏈接。
三 總結(jié)
1 單例模式不應(yīng)被濫用,比如不能為了得到一個(gè)全局變量而創(chuàng)建單例,單例是用于控制對(duì)象的創(chuàng)建過(guò)程的。只有真正的目的是控制對(duì)象創(chuàng)建的過(guò)程或數(shù)量時(shí),才能考慮使用單例。在大部分情況下,單例模式是有代替方案的。比如經(jīng)典的數(shù)據(jù)庫(kù)連接類被以單例實(shí)現(xiàn),其實(shí)可以以對(duì)象池模式實(shí)現(xiàn)。
2 使用單例模式,盡量使用饑餓模式 ,只有你能預(yù)測(cè)這個(gè)類一定會(huì)被創(chuàng)建,那么就可以使用饑餓模式。如果,一定需要推遲對(duì)象的創(chuàng)建時(shí)間。那么不要使用 Double-checked locking 之類的方法的來(lái)提高效率,這將得不償失。
[1] DoubleCheckedLocking
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html