6. 单例模式(Singleton Pattern)
一、介绍
用途:在某些情况下,某些对象在整个程序运行的过程中只需要一个就可以了,或者不需要。举例:一台电脑可以连接多台打印机,但是当程序运行起来开始打印时,只允许一台打印机输出所打印的内容。简单的来说,单例模式(单件模式)的作用是在保证在整个应用程序的生命周期中,任何时刻,单例类的实例只能存在一个(或者一个都不存在)。作用:全局访问,实例化控制设计模式结构图:
二、代码实现
C# 代码实现:创建:/// <summary> /// 懒汉式单例模式 /// </summary> public class SingletonV0 { // 声明一个静态类的变量 private static SingletonV0 _singleton = null; //构造方法私有,防止外界用new()访问 private SingletonV0(){} //通过此方法获取实例 public static SingletonV0 GetInstance() { return _singleton ?? (_singleton = new SingletonV0()); } }
使用:
class Program { static void Main(string[] args) { Singleton singletonOne = Singleton. GetInstance(); Singleton singletonTwo = Singleton. GetInstance(); if (singletonOne.Equals(singletonTwo)) { Console.WriteLine("singletonOne 与 singletonTwo 代表同一个实例!"); } else { Console.WriteLine("singletonOne 与 singletonTwo 代表不同的实例!"); } } }
输出结果:
三、总结
单例模式的特点:1. 单例模式在程序的任何时刻都只有一个实例2. 单例的构造函数是私有的,外部程序想要访问这个单例的话,只能通过GetInstance()来请求3. 在GetInstance()内部实现 单例的不存在则创建,存在则返回
四、拓展
多线程情况下的单例模式:以上代码看上去很简单,单例模式的代码量不会超过10行,但是在多线程情况下就蛋疼了,当第一个线程进来,判断singleton为null,正准备要创建,第二个线程也进来了,这时候if判断singleton为null,这就会创建两个singleton的实例。解决方法:既然是多线程进来的,那我们就可以考虑线程锁;让一个线程先进if语句块,然后在外面将if语句块加锁,当第二个线程再进来时,就会阻塞处于阻塞状态,直到第一个线程弯沉if判断并且创建了singleton实例,再判断singleton的存在与否,执行接下来的代码,这样就完美解决。lock 是确保当一个线程位于代码的临界时,另一个线程不进入临界区,如果其他线程试图进入锁定代码时,则它将一直等待(直到该对象被释放)代码修改如下:public static Singleton GetInstance() { //下面使用了双重检查锁定 //第一重判断 if (singleton == null) { lock(syncObject) { //第二重判断 //在这里可以保证只实例化一次,即使再次调用也不会创建新的实例 if (singleton == null) { singleton = new Singleton(); } } } return singleton; }
懒汉式饿汉式单例类:
上述单例类为懒汉式单例类,因为只有调用GetInstance()才会创建singleton的实例,而下代码为饿汉式单例类namespace Singleton { public sealed class Singleton { private static readonly Singleton singleton = new Singleton(); private Singleton() { } public static Singleton GetInstance() { return singleton; } } }
在整个类被加载时,就会创建实例,而非调用GetInstance()再创建,故这是一种饿汉单例
真正的大师永远怀着一颗学徒的心。




浙公网安备 33010602011771号