單例模式的定義:
- 數學與邏輯學中,singleton定義為“有且僅有一個元素的集合”。
- 單例模式最初的定義出現于《設計模式》(艾迪生維斯理, 1994):“保證一個類僅有一個執行個體,并提供一個通路它的全局通路點。”
- Java中單例模式定義:“一個類有且僅有一個執行個體,并且自行執行個體化向整個系統提供。”
Java單例模式例子
public class Singleton {
private Singleton(){
}
private static volatile Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
通常單例模式在Java語言中,有如下幾種建構方式:
- 懶漢式—線程不安全:最基礎的實作方式,線程上下文單例,不需要共享給所有線程,也不需要加synchronize之類的鎖,以提高性能。
- 懶漢式—線程安全:加上synchronize之類保證線程安全的基礎上的懶漢模式,相對性能很低,大部分時間并不需要同步
- 餓漢方式。指全局的單例執行個體在類裝載時建構。
- 雙檢鎖式。在懶漢式基礎上利用synchronize關鍵字和volatile關鍵字確定第一次建立時沒有線程間競争而産生多個執行個體,僅第一次建立時同步,性能相對較高
- 登記式。作為建立類的全局屬性存在,建立類被裝載時建立
- 枚舉。java中枚舉類本身也是一種單例模式
單例模式的優缺點:
優點
1.執行個體控制
單例模式會阻止其他對象執行個體化其自己的單例對象的副本,進而確定所有對象都通路唯一執行個體。
2.靈活性
因為類控制了執行個體化過程,是以類可以靈活更改執行個體化過程。
缺點
1. 開銷
雖然數量很少,但如果每次對象請求引用時都要檢查是否存在類的執行個體,将仍然需要一些開銷。可以通過使用靜态初始化解決此問題。
2. 可能的開發混淆
使用單例對象(尤其在類庫中定義的對象)時,開發人員必須記住自己不能使用new關鍵字執行個體化對象。因為可能無法通路庫源代碼,是以應用程式開發人員可能會意外發現自己無法直接執行個體化此類。
3. 對象生存期
不能解決删除單個對象的問題。在提供記憶體管理的語言中(例如基于.NET Framework的語言),隻有單例類能夠導緻執行個體被取消配置設定,因為它包含對該執行個體的私有引用。在某些語言中(如 C++),其他類可以删除對象執行個體,但這樣會導緻單例類中出現懸浮引用