單例模式最初的定義出現於《設計模式》(艾迪生維斯理, 1994):“保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。” 特點:一是某個類只能有一個實例; 二是它必須自行創建這個實例; 三是它必須自行向整個系統提供這個實例。 一、經典實現 二、靜態構造函數實現 三、靜態變數實現 測試: ...
單例模式最初的定義出現於《設計模式》(艾迪生維斯理, 1994):“保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。”
特點:一是某個類只能有一個實例;
二是它必須自行創建這個實例;
三是它必須自行向整個系統提供這個實例。
一、經典實現
using System; namespace SingletonPattern { // 經典寫法 // sealed 阻止其他類從該類繼承 public sealed class ClassicalSample { // 用來保存唯一實例 private static ClassicalSample _classicalSample; // 鎖範圍 private static readonly object obj = new object(); // 私有構造函數,阻止外部new實例化 private ClassicalSample() { Console.WriteLine("實例化"); } // 統一該類的 public static ClassicalSample GetInstance() { // 減少鎖的開銷 if (_classicalSample == null) { // 防止多線程併發 lock (obj) { // if (_classicalSample == null) { _classicalSample = new ClassicalSample(); } } } Console.WriteLine("獲取實例"); return _classicalSample; } } }
二、靜態構造函數實現
using System; namespace SingletonPattern { public sealed class StaticConstructorSample { private static StaticConstructorSample _staticConstructorSample; private StaticConstructorSample() { Console.WriteLine("實例化"); } // 靜態構造函數:第一次使用的時候執行,且只執行一次 static StaticConstructorSample() { _staticConstructorSample = new StaticConstructorSample(); Console.WriteLine("靜態構造函數實例化"); } public static StaticConstructorSample GetInstance() { Console.WriteLine("獲取實例"); return _staticConstructorSample; } } }
三、靜態變數實現
using System; namespace SingletonPattern { public sealed class StaticVariableSample { private static readonly StaticVariableSample _StaticVariableSample = new StaticVariableSample(); private StaticVariableSample() { Console.WriteLine("實例化"); } public static StaticVariableSample GetInstance() { Console.WriteLine("獲取實例"); return _StaticVariableSample; } } }
測試:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace SingletonPattern { class Program { static void Main(string[] args) { ClassicalSampleTest(); StaticConstructorSampleTest(); StaticVariableSampleTest(); Console.Read(); } static void ClassicalSampleTest() { Console.WriteLine("經典單例模式測試"); TaskFactory taskFactory = new TaskFactory(); // 多線程測試的task組 List<Task> tasks = new List<Task>(); // 每個線程獲取實例集 List<ClassicalSample> list = new List<ClassicalSample>(); for (int i = 0; i < 60; i++) { tasks.Add(taskFactory.StartNew<ClassicalSample>(() => ClassicalSample.GetInstance()).ContinueWith((r) => { list.Add(r.Result); })); } taskFactory.ContinueWhenAll(tasks.ToArray(), p => { Console.WriteLine(""); Console.WriteLine("tasks組執行完成之後一共獲取了{0}次實例", p.Count()); Console.WriteLine("實例個數{0}", list.Distinct().Count()); }); } static void StaticConstructorSampleTest() { Console.WriteLine("靜態構造函數單例模式測試"); TaskFactory taskFactory = new TaskFactory(); // 多線程測試的task組 List<Task> tasks = new List<Task>(); // 每個線程獲取實例集 List<StaticConstructorSample> list = new List<StaticConstructorSample>(); for (int i = 0; i < 60; i++) { tasks.Add(taskFactory.StartNew<StaticConstructorSample>(() => StaticConstructorSample.GetInstance()).ContinueWith((r) => { list.Add(r.Result); })); } taskFactory.ContinueWhenAll(tasks.ToArray(), p => { Console.WriteLine(""); Console.WriteLine("tasks組執行完成之後一共獲取了{0}次實例", p.Count()); Console.WriteLine("實例個數{0}", list.Distinct().Count()); }); } static void StaticVariableSampleTest() { Console.WriteLine("靜態變數單例模式測試"); TaskFactory taskFactory = new TaskFactory(); // 多線程測試的task組 List<Task> tasks = new List<Task>(); // 每個線程獲取實例集 List<StaticVariableSample> list = new List<StaticVariableSample>(); for (int i = 0; i < 60; i++) { tasks.Add(taskFactory.StartNew(() => StaticVariableSample.GetInstance()).ContinueWith((r) => { list.Add(r.Result); })); } taskFactory.ContinueWhenAll(tasks.ToArray(), p => { Console.WriteLine(""); Console.WriteLine("tasks組執行完成之後一共獲取了{0}次實例", p.Count()); Console.WriteLine("實例個數{0}", list.Distinct().Count()); }); } } }