1. 什麼是單例安全
保證一個類只有一個實例的實現方法。多線程
2. 使用場景函數
頁面訪問計數器工具
須要保持狀態的工具類性能
需求不少,不能一一列舉了spa
3. 實現方.net
非線程安全線程
1 /// <summary> 2 /// 單例模式的實現 3 /// </summary> 4 public sealed class Singleton 5 { 6 //定義一個靜態變量來保存類的實例 7 private static Singleton _instance = null; 8 9 //定義私有構造函數,使外界不能建立該類實例 10 private Singleton() 11 { 12 } 13 /// <summary> 14 /// 定義公有方法提供一個全局訪問點,同時你也能夠定義公有屬性來提供全局訪問點 15 /// </summary> 16 /// <returns></returns> 17 public static Singleton Instance() 18 { 19 //若是類的實例不存在則建立,不然直接返回 20 if (_instance == null) 21 { 22 _instance = new Singleton(); 23 } 24 return _instance; 25 } 26 }
上面的單例模式的實如今單線程下確實是能夠的,可是在多線程環境下會存在兩個線程同時執行if (instance == null)
而且建立兩個不一樣的實例code
簡單線程安全對象
1 /// <summary> 2 /// 單例模式的實現 3 /// </summary> 4 public sealed class Singleton 5 { 6 // 定義一個靜態變量來保存類的實例 7 private static Singleton instance = null; 8 9 // 定義一個標識確保線程同步 10 private static readonly object padlock = new object(); 11 12 Singleton() 13 { 14 } 15 16 public static Singleton Instance() 17 { 18 // 當第一個線程運行到這裏時,此時會對locker對象 "加鎖", 19 // 當第二個線程運行該方法時,首先檢測到locker對象爲"加鎖"狀態,該線程就會掛起等待第一個線程解鎖 20 // lock語句運行完以後(即線程運行完以後)會對該對象"解鎖" 21 lock (padlock) 22 { 23 // 若是類的實例不存在則建立,不然直接返回 24 if (instance == null) 25 { 26 instance = new Singleton(); 27 } 28 } 29 return instance; 30 } 31 }
上面的例子解決了多線程的問題,可是每一個線程調用Instance()都會使用到鎖,而調用鎖的開銷較大,這個實現會有必定的性能損失。
雙重驗證線程安全
1 /// <summary> 2 /// 單例模式的實現 3 /// </summary> 4 public sealed class Singleton 5 { 6 // 定義一個靜態變量來保存類的實例 7 private static Singleton instance = null; 8 9 // 定義一個標識確保線程同步 10 private static readonly object padlock = new object(); 11 12 Singleton() 13 { 14 } 15 16 public static Singleton Instance() 17 { 18 // 當第一個線程運行到這裏時,此時會對locker對象 "加鎖", 19 // 當第二個線程運行該方法時,首先檢測到locker對象爲"加鎖"狀態,該線程就會掛起等待第一個線程解鎖 20 // lock語句運行完以後(即線程運行完以後)會對該對象"解鎖" 21 if (instance == null) 22 { 23 lock (padlock) 24 { 25 // 若是類的實例不存在則建立,不然直接返回 26 if (instance == null) 27 { 28 instance = new Singleton(); 29 } 30 } 31 } 32 return instance; 33 } 34 }
上面的例子在保證線程安全的同時提升了性能
靜態變量實現單例
1 /// <summary> 2 /// 單例模式的實現 3 /// </summary> 4 public sealed class Singleton 5 { 6 //在Singleton第一次被調用時會執行instance的初始化 7 private static readonly Singleton instance = new Singleton(); 8 9 private Singleton() 10 { 11 } 12 13 public static Singleton Instance() 14 { 15 return instance; 16 } 17 }
上面的例子利用.net的特性來完成單例模式的建立,也是線程安全的
4. 優勢
在內存中只有一個對象,節省內存空間;
避免頻繁的建立銷燬對象,能夠提升性能;
避免對共享資源的多重佔用,簡化訪問;
爲整個系統提供一個全局訪問點。