目錄
- 概念:
- 常見應用場景
- 優缺點:
- 實作方式:
-
- 1.餓漢式實作
- 2.懶漢式實作
- 3.雙重檢測瑣式(一般不用)
- 4.靜态内部類的實作(懶加載)
- 5.枚舉實作方式
概念:
單例:保證一個類,隻有一個執行個體,并且提供一個通路該執行個體的全局通路地。
常見應用場景
優缺點:
單例隻是隻生成一個執行個體,減少系統性能開銷
實作方式:
主要:
餓漢模式(線程安全,調用效率高,不能延時加載)
懶漢模式(線程安全,調用效率不高,延時加載)
其他
雙重檢測瑣式(由于JVM底層内部模型原因,偶爾會出現問題,不建議使用)
靜态内部類式(線程安全,調用效率高,可以延時加載)
枚舉單列(線程安全,調用效率高,不能延時加載)
1.餓漢式實作
優缺點:
當類被加載時就被被建立,如果沒有調用getInstance 時,這個類就不會被用到,造成資源浪費
建立步驟:
1.私有構造 2.靜态私有變量 2.公有靜态方法
public class Demo1 {
private static Demo1 demo1 = new Demo1();
private Demo1(){}
public static Demo1 getInstance(){
return demo1;
}
}
Demo1 demo1 = Demo1.getInstance();
2.懶漢式實作
優缺點:
資源利用效率高,但是每次調用getInstance() 方法都要同步,效率較低
建立步驟:
1.私有構造 2.私有靜态變量 2.公司有靜态方法
public class Demo {
private static Demo demo;
private Demo(){}
public synchronized static Demo getInstance(){
if (demo == null){
demo = new Demo();
}
return demo;
}
3.雙重檢測瑣式(一般不用)
4.靜态内部類的實作(懶加載)
要點:
外部沒有staitc 屬性,則不會像餓漢式那樣立即加載對象
隻有真正調用getInstance() 才會加載靜态内部類,加載類時線程安全的。instance是static final 類型,保證了記憶體中隻有這樣一個執行個體存在,而且隻能被指派一次,進而保證了線程安全性。兼備了并發高效調用和延遲加載的優勢。
public class Demo2 {
private static class SignalClass{
private static final Demo2 demo2 = new Demo2();
}
public static Demo2 getInstance(){
return SignalClass.demo2;
}
private Demo2(){
}
}
5.枚舉實作方式
優點:
實作簡單
枚舉本身就是單列模式,有JVM從根本上提供保障,避免通過反射和反序列化的漏洞
缺點:
無延遲加載
public enum Demo3 {
INSTANCE; //這個枚舉元素,本身就是單列對象
}
注意:反射可以破解上面幾種實作的方式,枚舉不可以