转自:https://www.cnblogs.com/goldendragon/p/9913600.html 
作者:小雨 

2018年11月6日       小雨

一、单例模式的定义

  确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例,是一种对象创建型模式,有如下3个要点:

  • 只能有一个实例
  • 必须是自行创建这个实例
  • 必须自行向整个系统提供这个实例

二、单例模式的结构

  • 一个类型为自身的静态私有成员变量 - 存储唯一实例
  • 一个私有的构造函数
  • 一个公有的静态成员方法 ,返回唯一实例,对象为自身
  1. class SingletonClass
  2.     {
  3.         private static SingletonClass _instance = null; //静态私有成员变量,存储唯一实例

  4.         private SingletonClass() //私有构造函数,保证唯一性
  5.         {
  6.         }

  7.         public static SingletonClass GetInstance() //公有静态方法,返回一个唯一的实例
  8.         {
  9.             if (_instance == null)
  10.             {
  11.                 _instance = new SingletonClass();
  12.             }
  13.             return _instance;
  14.         }
  15.     }

三、单例模式的两种书写方法

1.类被加载时就将自己实例化

  1. class SingletonClass
  2.     {
  3.         private static SingletonClass _instance = new SingletonClass();
  4.        
  5.         private SingletonClass()
  6.         {
  7.         }

  8.         public static SingletonClass GetInstance()
  9.         {
  10.             return _instance;
  11.         }
  12.     }
2.类在第一次被引用时将自己实例化
  1. class SingletonClass
  2.     {
  3.         private static SingletonClass _instance = null;
  4.         private static readonly object syncRoot = new object();

  5.         private SingletonClass()
  6.         {
  7.         }

  8.         public static SingletonClass GetInstance()
  9.         {
  10.             if (_instance == null)
  11.             {
  12.                 lock (syncRoot)
  13.                 {
  14.                     if (_instance == null)
  15.                     {
  16.                         _instance = new SingletonClass();
  17.                     }
  18.                 }
  19.             }
  20.             return _instance;
  21.         }
  22.     }

四、双重锁的运用分析

   上述代码中出现“If - Lock - If”结构模式,即双重检查锁定的双重判断机制:

  1. if (_instance == null) //第一重判断,先判断实例是否存在,不存在再加锁处理
  2.             {
  3.                 lock (syncRoot) //加锁,在某一时刻只允许一个线程访问
  4.                 {
  5.                     if (_instance == null) //第二重判断: 第一个线程进入Lock中执行创建代码,第二个线程处于排队等待状态,当第二个线程进入Lock后并不知道实例已创建,将会继续创建新的实例
  6.                     {
  7.                         _instance = new SingletonClass();
  8.                     }
  9.                 }
  10.             }

五、单例模式的优缺点

  • 封装了唯一性,可严格控制客户怎么访问及何时访问
  • 内存中只存在一个对象,可节约系统资源,提高系统性能
  • 单例类的扩展不方便
  • 单例类既提供了业务方法,又提供了创建对象的方法,将对象的创建和对象本身的功能耦合在一起

六、适用环境

  系统只需要一个实例对象,客户调用类的单个实例只允许使用一个公共访问点,除了公共访问点,不能通过其他途径访问该实例

09-03 20:18
查看更多