1.惡漢式
public class Singleton {
private static Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
return INSTANCE;
}
}
優點:類加載的時候就完成了創建對象,不用考慮線程同步問題
缺點:沒有實現懶加載的效果,如果創建了該對象而不使用,造成內存資源浪費
2.懶漢式
public class Singleton {
private static Singleton INSTANCE;
public static Singleton getInstance() {
if (INSTANCE==null) {
return new Singleton();
}
return INSTANCE;
}
}
優點:實現了懶加載的方式
缺點:多線程獲取單例對象時,由於對象還未創建,會導致創建多個實例,多線程非安全
3.懶漢式(線程同步)
public class Singleton {
private static Singleton INSTANCE;
public static synchronized Singleton getInstance() {
if (INSTANCE==null) {
return new Singleton();
}
return INSTANCE;
}
}
public class Singleton {
private static Singleton INSTANCE;
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
return new Singleton();
}
}
return INSTANCE;
}
}
缺點:第一種,每次都是訪問鎖,會造成資源浪費
第二種,多線程訪問時,null的條件同時成立,在訪問鎖時,由於鎖的監視器是類,JVM只存在一個class對象,雖然會進行線程同步,但是一個線程在創建對象並且進行對象地址賦值時,由於機器可能會進行指令性重排,導致還instance未賦值就運行另個一個線程的getInstance方法,返回的實例並未初始化
4.雙重檢查+防止指令性重排
public class Singleton {
private volatile static Singleton INSTANCE;
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
return new Singleton();
}
}
return INSTANCE;
}
}
優點:延遲加載,線程同步
5.靜態內部類
public class Singleton {
private static class SingletonInnerClass {
private static final Singleton instance = new Singleton();
}
public Singleton getInstance() {
return SingletonInnerClass.instance;
}
}
優點:實現了延遲加載,而且不用考慮線程同步,Singleton 類在被裝載時,靜態內部類並不會立即初始化,只有在調用創建實例方法時靜態內部類 纔會被裝載,實現了對象的初始化