在乙個jvm程序中,乙個類對應的例項物件有且只有乙個。
因為在乙個程式中,有些業務邏輯和流程是重複的、通用的,沒有必要在每次執行時再進行new相同物件的操作。
只進行一次new操作,沒有物件的頻繁建立和**,提高了jvm的執行響應速度。尤其是在高併發的情況下,對程式的執行有很大的提公升。
1、在多執行緒的場景中,如果單例物件是通用類還好,如果單例物件中有鎖的情況,是非常影響程式的執行速率;
2、單例物件在建立時,不能傳遞引數,否則就不算是單例物件了。
1、乙個私有的、全域性的、靜態的單例物件引用;
2、乙個私有建構函式;
3、乙個獲取該引用的方法。
基於類物件的建立時間不同,分為餓漢模式和懶漢模式兩種
不過如果細分的話,有五種:餓漢、懶漢、雙重校驗鎖、靜態內部類和列舉。
1.餓漢模式
–不管用不用,先載入了再說。
優點class
singleton
public
static singleton getinstace()
}
1、執行快:不管程式在以後會不會用到,在類載入的過程中,就把這個單例物件建立好,如果在後續的執行中有用到,呼叫getinstace()就直接獲取到這個單例物件了;
2、執行緒安全
坑
1、程式啟動慢,因為這個物件在程式啟動時就建立了;
2、程式占用記憶體較多,如果程式中有多個這種方式編寫的不同單例物件,堆中會有這些單例物件,但這些單例物件,有可能是在程式執行到某個分支才用到。
2.懶漢模式
(不推薦下面這個寫法)
–什麼時候用,什麼時候再載入,即延遲載入。
優點class
singleton
public
static singleton getinstace()
return instance;
}}
只有在第一次被用到的時候才建立。
坑
在多執行緒情況下併發呼叫getinstace(),會出現建立了多個例項,不能保證這個物件是單
例。改進1(不推薦下面這個寫法)
坑class
singleton
public
static
synchronized singleton getinstace()
return instance;
}}
1、在多執行緒場景下,雖然能保證物件的單例性,卻降低了程式的執行響應速度,因為每個要獲取這個單例物件的執行緒都需要進行的鎖的等待和獲取;
2、在執行instance = new singleton();這句話時,cpu實際上執行的是多條指令,也就會出現指令重排的情況,這樣有可能出現執行緒1只給instance引用賦了值,但值還沒有完全建立好,此時,執行緒2來了判斷引用不是null就以後獲取到這個單例物件的情況。
3.雙重校驗鎖
改進2
這樣修改後,用雙重檢查機制來保證在多執行緒的情況下,可以正常高效執行;class
singleton
public
static
synchronized singleton getinstace()
}}return instance;
}}
1、只有在instance為null時才獲取鎖,減小了多執行緒要獲取鎖的情況;
2、通過volatile關鍵字,來防止cpu進行指令重排,保證這個關鍵字對應的內容能順序執行。
4.靜態內部類
改進3(推薦)
通過內部類的方式,來實現多執行緒下的安全。class
singleton
private
singleton()
public
static
synchronized singleton getinstace()
}
這個方法是使用了jvm中關於類物件的定義,而且類是在有使用時才被載入。在jvm中,乙個class,只有乙個類物件!
5.列舉(推薦)
這個是比較更好的列舉實現方法 :enum singleton
}// 使用
singleton.instance.
fun1()
;
這個比較特殊,可以防止序列化、反射,不過是不能被繼承。//定義單例模式中需要完成的**邏輯
public
inte***ce
mysingleton
public
enum singleton implements
mysingleton};
public
static mysingleton getinstance()
}
總結:從速度和響應時間上看,餓漢模式比較好;
從程式記憶體的使用上看,懶漢模式比較好。
java的幾種單例模式
1 賴漢式 public class lazysingleton public static lazysingleton getinstance 2 餓漢式 public class hungrysingleton public static hungrysingleton getinstance ...
java單例模式的幾種寫法
private static final userservice userservice new userservice private userservice 採取預載入的方式,userservice在 classloader 載入userservice.class 已經宣告了物件 return ...
java單例模式幾種實現方式
目錄 單例模式的五種實現方式 1 餓漢式 2 懶漢式 3 double checklock實現單例 4 靜態內部類實現模式 5 列舉類 執行緒安全,呼叫效率高,但是不能延時載入 public class imageloader public static imageloader getinstanc...