介绍
什么是单例模式呢?
我们可以将其理解为,只能有一个实例的类。比较官方的一种说法是:确保一个类只有一个实例,并提供一个全局访问点。
实现思路
确保这个类只能有一个实例
如何确保这个类只能有一个实例呢?
如果我们要在外部类使用该类的一些属性和方法,那么我们就需要在外部类使用new关键字创建一个该类的实例。我们怎样让该类不能在外部类使用new创建实例呢?我们可以在该类内部定义一个私有的构造函数,那么这个类不能在外界通过new来创建实例了。(注:如果类中没有定义构造函数,那么编译器会帮我们生成一个公有的无参构造函数)
1 2 3 4 5 6 7 8 9 10
| public class Singleton { private static Singleton _instance;
private Singleton() { } }
|
提供一个全局访问点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Singleton { private static Singleton _instance;
private Singleton() { }
public static Singleton Instance { get { if(_instance == null) { _instance = new Singleton(); } return _instance; } } }
|
多线程时的解决方案
上面的单例模式在单线程中使用是没有任何问题的,但是在多线程下会出现两个线程同时访问该类属性的情况,出现这种情况时,两个线程在执行到条件(_instance == null)时都会判断为真,导致两个线程都会创建该类的实例,这样就违背了只有一个实例的初衷了,这种情况的解决的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class Singleton { private static Singleton _instance;
private static readonly object locker = new object();
private Singleton() { }
public static Singleton Instance { get { lock(locker) { if(_instance == null) { _instance = new Singleton(); } } return _instance; } } }
|