1.餓漢式
public class HungerySingleton {
//ClassLoader 類加載時立即實例化對象,僅實例化一次,線程安全的
private static HungerySingleton hungerySingleton = new HungerySingleton();
public static HungerySingleton getInstance(){
return hungerySingleton;
}
}
優點:僅實例化一次,線程是安全的。獲取實例的速度快
缺點:類加載時立即實例化對象,可能實例化的對象不被使用,造成內存的浪費。
2.懶漢式
public class HoonSingleton {
//不能保證實例對象的唯一性
private static HoonSingleton hoonSingleton = null;
public static HoonSingleton getInstance(){
if(hoonSingleton==null){
hoonSingleton = new HoonSingleton();
}
return hoonSingleton;
}
}
優點:獲取實例時才進行實例的初始化,節省系統資源
缺點:1、如果獲取實例時,初始化的工作量較多,加載速度會變慢,影響系統系能
2、每次獲取實例都要進行非空檢查,系統開銷大
3、非線程安全。當多個線程同時getInstance()時,可能hoonSingleton實例化未完成,hoonSingleton==null判斷均爲true,造成對象重複實例化。
3.雙重檢查鎖 DCL(double-checked locking)+ volatile
public class HoonSingleton {
private static volatile HoonSingleton hoonSingleton = null;
// 使用sync同步HoonSingleton.class 兩次判斷hoonSingleton是否爲null 避免併發導致hoonSingleton被重新實例化
// 並沒有對整個方法使用sync,鎖的粒度變小了,實現了實例對象的唯一性
public static HoonSingleton getInstance(){
if(hoonSingleton==null){
synchronized (HoonSingleton.class) {
if(hoonSingleton==null) {
hoonSingleton = new HoonSingleton();
}
}
}
return hoonSingleton;
}
優點:1、線程安全。注意加粗標記,進行雙重檢查,保證只在實例未初始化前進行同步,效率高。
2、對hoonSingleton使用volatile修飾符,避免實例化過程中產生的重排序。避免NPE拋出。
缺點:實例非空判斷,耗費一定資源
4.Holder方式 廣泛使用的一種單例模式
//聲明類的時候、成員變量中不聲明實例變量,而是放到內部靜態類中
public class HolderDemo {
private static class Holder{
private static HolderDemo instance = new HolderDemo();
}
public static HolderDemo getInstance(){
return Holder.instance;
}
}
優點:1、內部類只有在外部類被調用才加載,從而實現了延遲加載
2、線程安全。且不用加鎖。