一文帶你摸清設計模式之單例模式!
- 2022 年 6 月 4 日
- 筆記
本文將給大家介紹java中設計模式——單例模式;
單例模式:保證在⼀個JVM中,該對象只有⼀個實例存在;
適⽤場景:
1、某些類創建⽐較頻繁,對於⼀些⼤型的對象,這是⼀筆很⼤的系統開銷。
2、省去了new操作符,降低了系統內存的使⽤頻率,減輕GC壓⼒。
3、有些類如交易所的核⼼交易引擎,控制着交易流程,如果該類可以創建多個的話,系統完全亂了。(⽐如⼀個軍隊出現了多個司 令員同時指揮,肯定會亂成⼀團),所以只有使⽤單例模式,才能保證核⼼交易服務器獨⽴控制整個流程。
代碼:
1 public class Singleton{ 2 //持有私有靜態實例,防止被引用,賦值為null,目的就是實現延遲加載 3 private static Singleton instance = null; 4 5 6 //私有構造方法,防止被實例化。 7 private Singleton(){ 8 } 9 10 //創建實例 11 public static Singleton getInstance() 12 { 13 if (instance=null){ 14 instance=new Singleton(); 15 16 } 17 return instance; 18 //如果該對象被⽤於序列化,可以保證對象在序列化前後保持⼀致 19 public Object readReaslove(){ 20 return instance; 21 } 22 23 } 24 }
分類:
1.餓漢式:類初始化時創建單例,線程安全,但佔用內存空間大,適⽤於占內存⼩的場景,否則推薦使⽤懶漢式延遲加載;
public class Singleton{
private static Singleton instance = new Singleton();
//構造器私有, 外部就無法new這個對象,保證一個類中只有一個實例對象
private Singleton(){}
public static Singleton newInstance(){ return instance; } }
2.懶漢式:需要單例實例的時候再創建,需要考慮線程安全(性能不太好)
1 public class Singleton{ 2 private static Singleton instance = null;//定義一個靜態變量指向自己 3 private Singleton(){}//私有化構造方法 4 public static synchronized Singleton newInstance(){//加鎖, 5 if (instance == null){ 6 instance = new Singleton(); 7 } 8 } 9 return instance; 10 11 }
3.雙重檢驗鎖:假如兩個線程A、B,A執⾏了if (instance == null)語句,它會認為單例對象沒有創建,此時線程切到B也執⾏了同樣的語句,B也認為單例對象沒有創建,然後兩個線程依次執⾏同步代碼塊,並分別創建了⼀個單例對象。
1 public class Singleton{ 2 private static volatile Singleton instance = null; 3 private Singleton(){} 4 public static Singleton getInstance(){ 5 if (instance == null) 6 { synchronized (Singleton.class){ 7 if (instance == null){ 8 instance = new Singleton(); 9 10 } 11 } 12 } 13 return instance; 14 }
4.靜態內部類:可以同時保證延遲加載和線程安全。靜態內部類單例是如何實現懶加載的呢?(懶加載 :使⽤的時候再創建對象)⾸先,我們先了解下類的加載時機。
1 public class Singleton{ 2 private Singleton(){}//私有化構造方法 3 public static Singleton getInstance(){//對外提供獲取實例的公共方法 4 return InnerClass.Instance;} 5 private static class InnerClass{//定義靜態內部類 6 private final static Singleton Instance=new Singleton; 7 8 } 9 10 }
5.枚舉:
1 public enum Singleton{ 2 instance; 3 public void whateverMethod(){} 4 }