1.介紹
單例模式是一種常用的軟體設計模式,其定義是單例對象的類隻能允許一個執行個體存在。
2.實作思路與步驟
1).将該類的構造方法定義為私有方法,這樣其他處的代碼就無法通過調用該類的構造方法來執行個體化該類的對象,隻有通過該類提供的靜态方法來得到該類的唯一執行個體;
2).在該類内提供一個靜态方法,當我們調用這個方法時,如果類持有的引用不為空就傳回這個引用,如果類保持的引用為空就建立該類的執行個體并将執行個體的引用賦予該類保持的引用。
2.單例模式實作
1)、餓漢式
public class Singleton {
private final static Singleton instance= new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
優點:這種寫法比較簡單,就是在類裝載的時候就完成執行個體化。避免了線程同步問題。
缺點:在類裝載的時候就完成執行個體化,沒有達到延遲加載的效果。如果從始至終從未使用過這個執行個體,則會造成記憶體的浪費。
2)、懶漢式
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
優點:這種寫法起到了延遲加載的效果,僅适合于單線程環境
缺點: 如果在多線程下,一個線程進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另一個線程也通過了這個判斷語句,這時便會産生多個執行個體
3)、懶漢式(線程安全,同步方法)
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
優點:解決了線程不安全的問題
缺點: 效率低,每個線程都要執行getInstance()方法進行同步。而其實這個方法隻執行一次執行個體化代碼就夠了,後面的想獲得該類的執行個體,直接return就行了
5) 雙重檢查
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
雙重檢測概念對于多線程開發者來說不會陌生,如代碼中所示,我們進行了兩次if (singleton == null)檢查,這樣就可以保證線程安全了。這樣,執行個體化代碼隻用執行一次,後面再次通路時,判斷if (singleton == null),直接return執行個體化對象。
優點:線程安全;延遲加載;效率較高。