定义:确保一个类仅有一个实例,并提供一个访问它的全局访问点。
优点:在内存中只有一个对象,节省了内存空间
示例:
Singleton.cs
写法一:非线程安全
public class Singleton { //声明一个静态的类变量 private static Singleton singleton; /// <summary> /// 私有构造函数,避免外部代码new实例化对象 /// </summary> private Singleton() { } /// <summary> /// 实例化对象 /// </summary> /// <returns></returns> public static Singleton GetInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
写法二:简单线程安全
多线程程序中,多个线程同时访问Singleton类,调用GetInstance()方法,可能会创建多个对象,这种情况我们该如何处理呢?
遇到这种情况我们可以给进程上一把锁(lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待,直到该对象被释放[MSDN])。
public class Singleton { //声明一个静态的类变量 private static Singleton singleton; //程序运行时创建一个静态只读进程辅助对象 private static readonly object syncRoot = new object(); /// <summary> /// 私有构造函数,避免外部代码new实例化对象 /// </summary> private Singleton() { } /// <summary> /// 实例化对象 /// </summary> /// <returns></returns> public static Singleton GetInstance() { lock (syncRoot) { if (singleton == null) { singleton = new Singleton(); } } return singleton; } }
写法三:双重锁定线程安全
public class Singleton { //声明一个静态的类变量 private static Singleton singleton; //程序运行时创建一个静态只读进程辅助对象 private static readonly object syncRoot = new object(); /// <summary> /// 私有构造函数,避免外部代码new实例化对象 /// </summary> private Singleton() { } /// <summary> /// 实例化对象 /// </summary> /// <returns></returns> public static Singleton GetInstance() { //先判断实例是否存在,不存在再加锁处理 if (singleton==null) { lock (syncRoot) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
客户端调用:
protected void Page_Load(object sender, EventArgs e) { Singleton singleton1 = Singleton.GetInstance(); Singleton singleton2 = Singleton.GetInstance(); if (singleton1 == singleton2) { Response.Write("两个对象是同一个示例"); } }
测试结果:
输出:两个对象是同一个示例