單例模式的五種寫法
寫之前的話
這是從簡書移植來的。
單例模式的五種寫法
經典版單例模式
public class Singleton {
private static Singleton uniqueInstance;//利用一個靜態常量來記錄singleton類的唯一例項。
private Singleton() {
}
public static Singleton getInstance() {
if (uniqueInstance == null) {//注意,只有第一次才徹底執行這裡的程式碼
uniqueInstance = new Singleton();//延遲例項化 (lazy instantiaze)
}
return uniqueInstance;//如果uniqueInstance不是null,就表示之前建立過物件,
// 我們就直接跳到return語句
}
}
這個版本存在一些問題,當不止一個執行緒的時候,以兩個執行緒為例,兩個執行緒同時執行到 if (uniqueInstance == null) {}
時,因為兩個執行緒裡類此時都沒有例項化,因此這裡還會new兩個例項,所以經典模式只適合同步的情況下。
同步鎖單例模式
public class Singleton {
private static Singleton uniqueInstance;//利用一個靜態常量來記錄singleton類的唯一例項。
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {//注意,只有第一次才徹底執行這裡的程式碼
uniqueInstance = new Singleton();//延遲例項化 (lazy instantiaze)
}
return uniqueInstance;//如果uniqueInstance不是null,就表示之前建立過物件,
// 我們就直接跳到return語句
}
}
通過新增synchronized關鍵字到getInstance方法中,我們強迫每個進入執行緒中進入該方法的前提是別的執行緒離開該方法,不會有兩個執行緒同時進入該方法。這種單例模式是執行緒安全的,不過synchronized會影響程式的效能,只有第一次執行該方法例項化的時候才需要同步,一旦設定好uniqueInstance就不再需要同步這個方法了。因此之後每次呼叫這個方法,synchronized都是一種累贅。
急切式單例模式(直接在靜態變數建立單例)
public class Singleton {
private static Singleton uniqueInstance = new Singleton();//利用一個靜態常量來記錄singleton類的唯一例項。
private Singleton() {
}
public static Singleton getInstance() {
return uniqueInstance;//已經有單例了,直接使用就好了
}
}
利用這種寫法,JVM在家在這個類時馬上建立此唯一的單例。JVM保證任何執行緒在訪問uniqueInstance靜態變數時,一定先建立次例項。
雙重同步鎖單例模式
public class Singleton {
//volatile 關鍵詞確保:當uinqueInstance變數被初始化成Singleton例項時,
// 多個執行緒正確的處理uniqueInstance變數
private volatile static Singleton uniqueInstance;//利用一個靜態常量來記錄singleton類的唯一例項。
private Singleton() {
}
//防止多執行緒出錯
public static Singleton getInstance() {//檢查例項,如果不存在,進入同步區塊。
if (uniqueInstance == null) {//注意,只有第一次才徹底執行這裡的程式碼
synchronized (Singleton.class) {
//進入區塊後在檢查一次,如果仍是null,才建立例項。
if (uniqueInstance == null) {
uniqueInstance = new Singleton();//延遲例項化 (lazy instantiaze)
}
}
}
return uniqueInstance;//如果uniqueInstance不是null,就表示之前建立過物件,
// 我們就直接跳到return語句
}
}
想比同步鎖單例模式,這種做法可以大大提高效能。
volatile 關鍵詞:當uinqueInstance變數被初始化成Singleton例項時,多個執行緒正確的處理uniqueInstance變數。
用列舉實現單例模式
public enum Singleton {
instance;
private xxxxxx instance;
Singleton () {
instance = new xxxxxx ();
}
public xxxxxx getInstance() {
return instance;
}
}
上面的類xxxxxx
是我們要應用單例模式的資源,具體可以表現為網路連線,資料庫連線,執行緒池等等。獲取資源的方式很簡單,只要使用Singleton.instance.getInstance()
即可獲得所要例項。在列舉中我們明確了構造方法限制為私有,在我們訪問列舉例項時會執行構造方法,同時每個列舉例項都是static final型別的,也就表明只能被例項化一次。在呼叫構造方法時,我們的單例被例項化。 也就是說,因為enum中的例項被保證只會被例項化一次,所以我們的instance也被保證例項化一次。
結束
以上就是單例模式的幾種用法,每種方法都有各自優缺點,單元素的列舉型別已經成為實現Singleton的最佳方法。
相關文章
- 單例模式的六種寫法單例模式
- 單例模式的七種寫法單例模式
- Java:單例模式的七種寫法Java單例模式
- 單例模式有幾種寫法?單例模式
- 單例模式(下) – 聊一聊單例模式的幾種寫法單例模式
- 單例模式(下)---聊一聊單例模式的幾種寫法單例模式
- 單例模式(下) - 聊一聊單例模式的幾種寫法單例模式
- 設計模式 - 單例模式Singleton的8種寫法設計模式單例
- 單例模式你會幾種寫法?單例模式
- 回字有四種寫法,那你知道單例有五種寫法嗎單例
- 單例模式的七種寫法,你都知道嗎?單例模式
- 孔乙己的疑問:單例模式有幾種寫法單例模式
- 單例的幾種寫法單例
- 面試中單例模式有幾種寫法?面試單例模式
- 單例模式的正確寫法單例模式
- Python單例的一種簡單寫法Python單例
- 面試突擊50:單例模式有幾種寫法?面試單例模式
- 五種方式實現 Java 單例模式Java單例模式
- 八、目前JDK中,單例模式這3種寫法你知道嗎?JDK單例模式
- Java基礎系列-單例的7種寫法Java單例
- 論單例的寫法單例
- 單例模式的五種實現方式及優缺點單例模式
- 【設計模式】實現執行緒安全單例模式的五種方式設計模式執行緒單例
- Singleton——單例模式(8種)單例模式
- 單例模式的各種實現單例模式
- Kotlin下的5種單例模式Kotlin單例模式
- Java併發程式設計中的設計模式解析(二)一個單例的七種寫法Java程式設計設計模式單例
- CSS三欄佈局的五種寫法CSS
- JS實現單例模式的多種方案JS單例模式
- 單例模式的各種實現方式(Java)單例模式Java
- Java 實現單例模式的 9 種方法Java單例模式
- Python單例模式(Singleton)的N種實現Python單例模式
- 如何寫出一個好的單例模式單例模式
- 單例模式:5種實現方式單例模式
- 整理下java六種單例模式Java單例模式
- 面試之---手寫單例模式面試單例模式
- 實現單例模式的 9 種方法,你知道幾種?單例模式
- 五種演繹法拯救單調