單例模式,就是同一時間只有一個該類的對象存在安全
#region 單例模式一 //簡單版本 多線程不安全。能夠會在同一時間點上都建立一個實例,雖然通常不會出異常錯誤,可是起碼不是咱們談論的只保證一個實例了。 public sealed class Singleton_1 { private string name; public string Name { set { if (string.IsNullOrEmpty(this.name)) { name = value; } } get { return this.name; } } private static Singleton_1 instance; private Singleton_1(string name) { this.Name = name; } public static Singleton_1 Instance(string name) { if (instance == null) { instance = new Singleton_1(name); } return instance; } } #endregion #region 單例模式二 // 經過readonly實現單例。 public sealed class Singleton_2 { private string name; public string Name { set { if (string.IsNullOrEmpty(this.name)) { name = value; } } get { return this.name; } } private Singleton_2(string name) { this.Name = name; } private static readonly Singleton_2 instance = new Singleton_2("惟一實例"); public static Singleton_2 Instance { get { return instance; } } } #endregion #region 單例模式三 // 利用volatile關鍵字保證volatile在被訪問以前被賦值實例。 // 利用lock保證多線程安全。 // 補充: volatile的做用是: 做爲指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值. public sealed class Singleton_3 { // 依然是靜態自動hold實例 private static volatile Singleton_3 instance = null; // Lock對象,線程安全所用 private static object syncRoot = new Object(); private Singleton_3() { } public static Singleton_3 Instance { get { if (instance == null) { lock (syncRoot) { if (instance == null) instance = new Singleton_3(); } } return instance; } } } #endregion #region 單例模式四 // 在模式二的基礎上加了一個靜態構造函數。 public class Singleton_4 { private static readonly Singleton_4 instance = new Singleton_4(); private Singleton_4() { } static Singleton_4() { } // 聲明靜態構造函數就是爲了刪除IL裏的BeforeFieldInit標記 // 以保證靜態自動在使用以前被初始化 public static Singleton_4 Instance { get { return instance; } } } #endregion #region 單例模式五 //經過lazy<T>延時初始化,多線程安全,只會初始化一次 之後每次調用都使用它。 public class Singleton_5 { private static readonly Lazy<Singleton_5> instance = new Lazy<Singleton_5>(() => new Singleton_5()); private Singleton_5() { } public static Lazy<Singleton_5> Instance { get { return instance; } } } #endregion class 單例模式 { static void Main(string[] args) { # region 單例模式一 //Singleton_1 singleton = Singleton_1.Instance("惟一實例"); //Console.WriteLine(singleton.Name); //Singleton_1 singleton_new = Singleton_1.Instance("另外一個實例"); //Console.WriteLine(singleton_new.Name); #endregion #region 單例模式二 //Singleton_2 singleton = Singleton_2.Instance; //Console.WriteLine(singleton.Name); //singleton.Name = "更名了"; //Console.WriteLine(singleton.Name); //Singleton_2 singleton2 = Singleton_2.Instance; //Console.WriteLine(singleton == singleton2); #endregion #region 單例模式三 //Singleton_3 singleton = Singleton_3.Instance; //Singleton_3 singleton2 = Singleton_3.Instance; //Console.WriteLine(singleton == singleton2); #endregion #region 單例模式四 //Singleton_4 singleton = Singleton_4.Instance; //Singleton_4 singleton2 = Singleton_4.Instance; //Console.WriteLine(singleton == singleton2); #endregion #region 單例模式五 Lazy<Singleton_5> singleton = Singleton_5.Instance; Lazy<Singleton_5> singleton2 = Singleton_5.Instance; Console.WriteLine(singleton == singleton2); #endregion } }