一、单例模式的定义
确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例,是一种对象创建型模式,有如下3个要点:
- 只能有一个实例
- 必须是自行创建这个实例
- 必须自行向整个系统提供这个实例
二、单例模式的结构
- 一个类型为自身的静态私有成员变量 - 存储唯一实例
- 一个私有的构造函数
- 一个公有的静态成员方法 ,返回唯一实例,对象为自身
1 class SingletonClass 2 { 3 private static SingletonClass _instance = null; //静态私有成员变量,存储唯一实例 4 5 private SingletonClass() //私有构造函数,保证唯一性 6 { 7 } 8 9 public static SingletonClass GetInstance() //公有静态方法,返回一个唯一的实例 10 { 11 if (_instance == null) 12 { 13 _instance = new SingletonClass(); 14 } 15 return _instance; 16 } 17 }
三、单例模式的两种书写方法
1.类被加载时就将自己实例化
1 class SingletonClass 2 { 3 private static SingletonClass _instance = new SingletonClass(); 4 5 private SingletonClass() 6 { 7 } 8 9 public static SingletonClass GetInstance() 10 { 11 return _instance; 12 } 13 }
2.类在第一次被引用时将自己实例化
1 class SingletonClass 2 { 3 private static SingletonClass _instance = null; 4 private static readonly object syncRoot = new object(); 5 6 private SingletonClass() 7 { 8 } 9 10 public static SingletonClass GetInstance() 11 { 12 if (_instance == null) 13 { 14 lock (syncRoot) 15 { 16 if (_instance == null) 17 { 18 _instance = new SingletonClass(); 19 } 20 } 21 } 22 return _instance; 23 } 24 }
四、双重锁的运用分析
在上述代码中出现“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 }
五、单例模式的优缺点
- 封装了唯一性,可严格控制客户怎么访问及何时访问
- 内存中只存在一个对象,可节约系统资源,提高系统性能
- 单例类的扩展不方便
- 单例类既提供了业务方法,又提供了创建对象的方法,将对象的创建和对象本身的功能耦合在一起
六、适用环境
系统只需要一个实例对象,客户调用类的单个实例只允许使用一个公共访问点,除了公共访问点,不能通过其他途径访问该实例