C#設計模式——單例模式的實現

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. 優勢

在內存中只有一個對象,節省內存空間;

避免頻繁的建立銷燬對象,能夠提升性能;

避免對共享資源的多重佔用,簡化訪問;

爲整個系統提供一個全局訪問點。

相關文章
相關標籤/搜索