一 基本概念
單例模式是一種為類 提供唯一實例的設計模式。單例模式的目的是為了控制對象的創建,它可以限制創建的數目為一,但在情況改變的時候,也允許靈活地創建更多的對象。因為只有一個實例,所以也只有一套實例的類變量的拷貝,這很像 static 變量。
在 JAVA 中,單例模式不應該被當作一種實現全局變量的方法。更多的,如同工廠模式,單例模式允許你通過 確認某些先決條件是否滿足 或者 以 lazily 方式按需創建的方式 來封裝和控制創建過程。
二 編程實現
1 饑餓模式 Eager Singleton












2 懶漢模式 Lazy Singleton















由于只有一個私有構造器,所以單例類是無法被集成的。基于這一點,單例模式并不是一個面向對象模式,僅僅是一個基于對象的模式。
3 饑餓模式基本沒有問題,懶漢模式則容易出現一些錯誤的編程方法
1)
// error, no synchronization on method
public static MySingleton getInstance() {
if (fInstance==null) {
fInstance = new MySingleton();
}

return fInstance;
}
2)










3) Double-checked locking 不要使用









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