Singleton模式主要作用是保證在Java應用程式中,一個類Class只有一個例項存在。
- 餓漢式,JVM在載入這個類時就馬上建立此唯一的單例例項
- 懶漢式,單例例項在第一次被使用時構建,而不是在JVM在載入這個類時就馬上建立此唯一的單例例項
- 餓漢式程式碼例項
public class Singleton {
private static Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getINSTANCE() {
return INSTANCE;
}
}
複製程式碼
- 懶漢式程式碼
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getINSTANCE() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
複製程式碼
- 懶漢式程式碼2(雙重加鎖版本)
public class Singleton {
/**
* volatile保證,當uniqueInstance變數被初始化成Singleton例項時,
* 多個執行緒可以正確處理uniqueInstance變數
*/
private static volatile Singleton INSTANCE;
private Singleton() {
}
public static Singleton getINSTANCE() {
//檢查例項,如果不存在,就進入同步程式碼塊
if (INSTANCE == null) {
//只有第一次才徹底執行這裡的程式碼
synchronized (Singleton.class) {
//進入同步程式碼塊後,再檢查一次,如果仍是null,才建立例項
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
複製程式碼
- 懶漢式程式碼3(靜態內部類版本)
靜態內部實現的單例是懶載入的且執行緒安全。 只有通過顯式呼叫 getInstance 方法時,才會顯式裝載 SingletonHolder 類,從而例項化 instance(只有第一次使用這個單例的例項的時候才載入,同時不會有執行緒安全問題)。
public class Singleton {
//靜態內部類
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {
}
public static Singleton getINSTANCE() {
return SingletonHolder.INSTANCE;
}
}
複製程式碼
- 餓漢式程式碼2(列舉模式)
使用列舉實現單例更簡潔,自動支援序列化機制,絕對防止多次例項化 (如果單例類實現了Serializable介面,預設情況下每次反序列化總會建立一個新的例項物件
public enum Singleton {
INSTANCE;
public void doSomething(){
//doSomething
}
}
複製程式碼
列舉單例的使用
Singleton instance = Singleton.INSTANCE;
instance.doSomething();
複製程式碼