設計模式建立型之單例模式
阿新 • • 發佈:2020-08-12
單例就是在應用程式中保證型別只有一個例項。
建立一個簡單的單例,程式碼如下
public class Singleton { private Singleton() //構造私有化,防止外部New { } private static Singleton _singleton = null; //對外提供一個獲取例項的方法 public static Singleton CreateInstance() { if (_singleton == null) { _singleton= new Singleton(); } return _singleton; } }
這樣存在的問題是多執行緒時,執行緒不安全,升級如下
public class Singleton { private Singleton() //構造私有化,防止外部New { } private static Singleton _singleton = null; private static object _lockObject = new object(); //對外提供一個獲取例項的方法 public static Singleton CreateInstance() { lock (_lockObject)//確保任意時刻只有一個執行緒訪問 { if (_singleton == null) { _singleton = new Singleton(); } }return _singleton; } }
執行緒安全,但是有效能問題,繼續升級如下
public class Singleton { private Singleton() //構造私有化,防止外部New { } private static Singleton _singleton = null; private static object _lockObject = new object(); //對外提供一個獲取例項的方法 public static Singleton CreateInstance() { if (_singleton == null) //對像不為空時直接返回,不用排隊取鎖,提高效能 { lock (_lockObject)//確保任意時刻只有一個執行緒訪問 { if (_singleton == null) { _singleton = new Singleton(); } } } return _singleton; } }
這樣通過雙if加lock ,就實現了一個懶漢式的單例。
懶漢式 :需要才建立例項,延遲載入
餓漢式 :第一時間建立例項,類載入就馬上建立
接下來實現兩種餓漢式的單例
1靜態方法中初始化物件
public class Singleton { private Singleton() //構造私有化,防止外部New { } private static Singleton _singleton = null; //靜態建構函式:由CLR保證單例,程式第一次使用這個型別前被呼叫,且只調用一次 static Singleton() { _singleton = new Singleton(); } //對外提供一個獲取例項的方法 public static Singleton CreateInstance() { return _singleton; } }
2 靜態欄位賦值
public class Singleton { private Singleton() //構造私有化,防止外部New { } //靜態欄位:在第一次使用這個類之前,由CLR保證,初始化且只初始化一次 private static Singleton _singleton = new Singleton(); //對外提供一個獲取例項的方法 public static Singleton CreateInstance() { return _singleton; } }
單例模式建立的例項不會自動釋放記憶體,會長時間佔據記憶體空間。適用場景執行緒池,資料庫連線池,計數器/流水號生成器,配置檔案讀取,IOC容器。