今天来介绍所有设计模式中结构最简单的设计模式单例模式, 它的核心结构中只包含一个被称为单例类的特殊类.
要想完成单例类的设计, 我们要遵循一下原则即可:
1, 一个类只能有一个实例
2, 确保该实例对外有一个访问入口(保证我们的系统可以从这个入口拿到该类的唯一实例)
3, 将单例类的构造函数私有化 (private), 当构造函数被私有化之后, 外部无法通过 new 单例类() 的方法来实例化该类. 既然外部无法直接实例化该类, 那就要求该类的实例要自己去创建了~
下面我们先看一个最简单的单例类的实现:
- /// <summary>
- /// 单例类
- /// </summary>
- public class Singleton
- {
- private Singleton instance = null;
- // 构造函数私有化
- private Singleton()
- {
- }
- // 外部通过该类的唯一入口 (GetInstance 方法) 获得单例类的实例
- public Singleton GetInstance()
- {
- if (instance == null)
- instance = new Singleton();
- return instance;
- }
- }
其实上面的代码只是简单的介绍单例类的写法, 下面我们来介绍一下饿汉式单例和懒汉式单例.
- /// <summary>
- /// 饿汉式单例类
- /// </summary>
- public class Singleton
- {
- private static Singleton instance = new Singleton();
- // 构造函数私有化
- private Singleton()
- {
- }
- // 外部通过该类的唯一入口 (GetInstance 方法) 获得单例类的实例
- public Singleton GetInstance()
- {
- return instance;
- }
- }
饿汉式单例类在类初始化的时候, 直接 new 了一个单例类的实例并赋值给静态私有变量, 因为静态变量归类所有, 所以程序自始至终只会有一个实例.
二, 懒汉式单例类
上面的代码看上去很完美, 并没有什么问题. 但是大家可以想一个问题, 在高并发大流量的情况下, 如果多个应用程序对该类进行实例化时(并发调用 GetInstance 方法时), 有可能会导致单例类创建多个实例. 所以, 为了解决并发创建多个实例的问题, 我们可以对实例的创建过程加锁. 这就衍生出来了懒汉式单例类.
- /// <summary>
- /// 懒汉式单例类(高并发处理)
- /// </summary>
- public class Singleton
- {
- private static Singleton instance = null;
- private static readonly object syncRoot = new object();
- // 构造函数私有化
- private Singleton()
- {
- }
- // 外部通过该类的唯一入口 (GetInstance 方法) 获得单例类的实例
- public static Singleton GetInstance()
- {
- if (instance == null)
- {
- lock (syncRoot)// 加锁之后只允许单线程访问, 但是此处可能有其他的并发现成在此处等待执行
- {
- // 因为锁外面有可能并发线程在等待执行, 为了防止线程实例化类之后, 后面的线程继续实例化对象, 应该在加一层判断
- if (instance == null)
- {
- instance = new Singleton();
- }
- }
- }
- return instance;
- }
- }
来源: https://www.cnblogs.com/caoruipeng/p/9665534.html