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


1. 什么是單例

保證一個類只有一個實例的實現方法。


2. 使用場景

頁面訪問計數器

需要保持狀態的工具類

需求很多,不能一一列舉了


3. 實現方

非線程安全

  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)並且創建兩個不同的實例


簡單線程安全

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

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

避免頻繁的創建銷毀對象,可以提高性能;

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM