设计模式-1.4单例模式
单例模式:一个类只允许生成一个实例,并提供一个访问它的全局访问点。
1 private static Singleton instance; 2 3 /// <summary> 4 ///构造方法私有化,不让外界new新的实例, 5 /// </summary> 6 private Singleton() 7 { 8 } 9 10 /// <summary> 11 /// 获得实例的唯一一个全局访问点 12 /// </summary> 13 /// <returns></returns> 14 public static Singleton getInstance() 15 { 16 if (instance == null) 17 { 18 instance = new Singleton(); 19 } 20 return instance; 21 } 22 }
注意事项:
多线程时的单例:多个线程同时访问时可能会造成多个单例。
1.懒汉式单例类:在第一次被引用时才将自己实例化
方法1:lock锁
1 class Singleton 2 { 3 private static Singleton instance; 4 //程序运行时创建一个静态只读的辅助对象 5 private static readonly Object syncRoot = new Object(); 6 7 /// <summary> 8 ///构造方法私有化,不让外界new新的实例, 9 /// </summary> 10 private Singleton() 11 { 12 } 13 14 /// <summary> 15 /// 获得实例的唯一一个全局访问点 16 /// </summary> 17 /// <returns></returns> 18 public static Singleton getInstance() 19 { 20 lock (syncRoot)//为什么不直接锁instance,第一次还没生成实例就去锁定是错误的 21 { 22 if (instance == null) 23 { 24 instance = new Singleton(); 25 } 26 } 27 return instance; 28 } 29 }
方法二:双重锁定(double-check locking)。方法一中每次进来都需要上锁,程序效率降低。
1 class Singleton 2 { 3 private static Singleton instance; 4 //程序运行时创建一个静态只读的辅助对象 5 private static readonly Object syncRoot = new Object(); 6 7 /// <summary> 8 ///构造方法私有化,不让外界new新的实例, 9 /// </summary> 10 private Singleton() 11 { 12 } 13 14 /// <summary> 15 /// 获得实例的唯一一个全局访问点 16 /// </summary> 17 /// <returns></returns> 18 public static Singleton getInstance() 19 { 20 //实例为空的时候才去锁定 21 if (instance == null) 22 { 23 lock (syncRoot)//为什么不直接锁instance,第一个还没生成实例就要去锁定是错误的 24 { 25 if (instance == null)//为什么上面判断了instance为空,此处还要判断,此处不判断仍然可能产生多个实例 26 { 27 instance = new Singleton(); 28 } 29 } 30 } 31 return instance; 32 } 33 }
2.饿汉式单例类:被加载时就将自己实例化。
1 //阻止派生,派生可能增加新的实例 2 public sealed class Singleton 3 { 4 5 private static readonly Singleton instance = new Singleton(); 6 private Singleton() 7 { 8 9 } 10 public static Singleton getInstance() 11 { 12 return instance; 13 } 14 }