单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 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()); }); } } }