C#设计模式:单例模式(Singleton)
一,单例模式:它的主要特点不是根据客户程序调用生成一个新的实例,而是控制某个类型的实例数量-唯一一个,就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点。
1,静态方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SingletonPattern { public class Singleton { private Singleton() { Console.WriteLine("{0}被创建了,线程ID{1}!", this.GetType().Name, Thread.CurrentThread.ManagedThreadId); } public static Singleton _singleton = null; public static object lockObject = new object(); /// <summary> ///创建实例 /// </summary> /// <returns></returns> public static Singleton CreateIntance() { if (_singleton == null) //保证对象初始化之后的所有线程,不需要等待锁 { Console.WriteLine("准备进入Lock"); lock (lockObject) //保证只有一个进程去判断 { if (_singleton == null) //保证为空才正的创建 { _singleton = new Singleton(); } } } return _singleton; } public void Show() { Console.WriteLine("显示!!!"); } } }
2,静态构造单例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SingletonPattern { public class SingletonSecond { public static SingletonSecond _singleton = null; private SingletonSecond() { Console.WriteLine("{0}被创建了,线程ID{1}!", this.GetType().Name,Thread.CurrentThread.ManagedThreadId); } /// <summary> ///1,静态构造函数:由CLR保证,再第一次使用这个类型之前,调用而且之调用一次 /// </summary> /// <returns></returns> static SingletonSecond() { _singleton = new SingletonSecond(); } public static SingletonSecond CreateIntance() { return _singleton; } public void Show() { Console.WriteLine("显示!!!"); } } }
3,静态变量单例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SingletonPattern { public class SingletonThird { private SingletonThird() { Console.WriteLine("{0}被创建了,线程ID{1}!", this.GetType().Name,Thread.CurrentThread.ManagedThreadId); } /// <summary> /// 静态变量:会在类型第一次使用的时候初始化,而且只初始化一次 /// </summary> private static SingletonThird _singleton = new SingletonThird(); public static SingletonThird CreateIntance() { return _singleton; } public void Show() { Console.WriteLine("显示!!!"); } } }
4,输出结果
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SingletonPattern { /// <summary> /// 单例模式 /// 保证整个进程中该对象只被实例化一次,常驻内存,根据这个特点:单例模式有三种写法:Singleton,SingletonSecond,SingletonThird, /// 普通的类型是需要的时候初始化,使用完被GC回收,跟静态不一样 /// </summary> class Program { static void Main(string[] args) { //Singleton singleton = Singleton.CreateIntance(); //for (int i = 0; i < 10; i++) //{ // Singleton singleton = Singleton.CreateIntance(); // singleton.Show(); //} Console.WriteLine("---------------------------------------"); //多线程测试调用,结果也是公用一个对象,之调用一次构造函数 List<IAsyncResult> asyncResults = new List<IAsyncResult>(); for (int i = 0; i < 5; i++) { asyncResults.Add(new Action(() => { Singleton singleton = Singleton.CreateIntance(); singleton.Show(); }).BeginInvoke(null,null)); //会启动一个异步多线程的调用 } ////判断多线程是否执行完了 while (asyncResults.Count(r => !r.IsCompleted) > 0) { Thread.Sleep(10); } Console.WriteLine("---------------------------------------"); //多线程测试调用,结果也是公用一个对象,之调用一次构造函数 List<IAsyncResult> asyncResults2 = new List<IAsyncResult>(); for (int i = 0; i < 5; i++) { asyncResults2.Add(new Action(() => { SingletonSecond singleton = SingletonSecond.CreateIntance(); singleton.Show(); }).BeginInvoke(null, null)); //会启动一个异步多线程的调用 } ////判断多线程是否执行完了 while (asyncResults2.Count(r => !r.IsCompleted) > 0) { Thread.Sleep(10); } Console.WriteLine("---------------------------------------"); List<IAsyncResult> asyncResults3 = new List<IAsyncResult>(); for (int i = 0; i < 5; i++) { asyncResults3.Add(new Action(() => { SingletonThird singleton = SingletonThird.CreateIntance(); singleton.Show(); }).BeginInvoke(null, null)); //会启动一个异步多线程的调用 } Console.ReadKey(); } } }
得到的结果都是一样的,共有对象,都是被构造一次
二,单例模式的扩展
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _1_2单例模式 { class Program { static void Main(string[] args) { Demo.Instance.Say(); } } public class SingleTon<T> where T : new() { private static T _instance; public static T Instance { get { return _instance = new T(); } } } public class Demo : SingleTon<Demo> { public void Say() { Console.WriteLine("单例模式"); } } }
三:单例模式(Singleton)的特点
1,私有构造函数,原因使用者不可以实例,则单例模式全局只有一个实例
2,静态实例,因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以定义一个私有的静态全局变量instance来保存该类的唯一实例;
3,单例模式避免多线程并发造成实例并不唯一,则需要用到锁。锁的解析如以上代码。