一、单例模式(Singleton Pattern)
单例模式要求一个类只能有一个实例,并且提供了一个全局的访问点。
比如说,中国主席的职位是Singleton,法律规定主席选举,任何时间只能有一个主席。
1、逻辑模型图:
2、物理模型图:
3、具体实现:
3.1、懒汉式单例:
//懒汉式单例 public sealed class Singleton//类设置属性为密封,不能被继承。 { static Singleton instance=null; Singleton() {} public static Singleton Instance { get { if(instance==null) { instance=new Singleton(); } return instance; } } } //这种实现方式,不是线程安全的,因为多线程的时候,可能会得到Singleton类的多个实例。 //假如有两个线程都去判断if(instance==null)并且得到结果为true,这时两个线程 //都会创建类Singleton的实例,违背了单例模式只能有一个类对象的实例的原则。
3.2、线程安全的单例
public sealed class Singleton { static Singleton instance=null; static readonly object padlock=new object();//进程辅助对象 Singleton() { } public static Singleton Instance { get { lock(padlock) { if(instance==null) { instance=new Singleton(); } return instance; } } } } //对于线程来说是安全的,首先创建了一个进程的辅助对象,线程进入时先对padlock加锁 //然后在检测对象是否被创建,这样可以确保只有一个实例被创建,而且加入了锁,导致程序只有 //一个线程可以进去,对象实例有最先进入的那个线程创建,后面进来的线程进入时if(instance==null)为false //不会再去创建对象实例,这种方式增加了额外的开销,损失了性能。
3.3、双重锁定
public sealed class Singleton { static Singleton instance=null; static readonly object padlock=new object(); Singleton() { } public static Singleton Instance { get { if(instance==null) { lock(padlock) { if(instance==null) { instance=new Singleton(); } } } return instance; } } } //对于多线程是安全的,而且并不是线程每次都加锁,只有判断对象实例没有被创建的时候才会加锁 //加锁还再进行对象是否被创建的判断。解决了线程并发的问题,但是实际上需要这样实现,大多数我们会
//使用静态初始化,但是静态初始化有自己的缺点,无法实现延迟初始化
3.4、静态初始化
public sealed class Singleton { static readonly Singleton instance=new Singleton(); //静态初始化的无参构造方法 static Singleton() { } Singleton() { } public static Singleton Instance { get { return instance; } } } //类标记为sealed不能继承,因为继承可能会增加实例。 //变量标记为readonly,表示只能在静态初始化时候或者在构造方法中分配变量。
3.5、延迟初始化
//如果类,结构,代理,枚举是外置,那么修饰符只有public和internal,默认是internal //如果是内置的,修饰符默认是private //举例: class A{}//类A是internal,internal表示同一个程序集中所有代码都可以访问类型或者成员
//其他程序集不可以访问。 //举例:class A // { // class B{}//类B是private // } public sealed class Singleton { Singleton()//类的构造函数默认为private { } public static Singleton Instance { get { return Lazy.instance; } } class Lazy//lazy默认是internal { static Lazy() { } internal static readonly Singleton instance=new Singleton(); } } //初始化的时候有一个Lazy类的一个静态成员来完成,这样实现了延迟初始化。
4、实现总结:
Singleton单例模式构造方法可以设置为protected,允许子类继承。
单例模式不要支持实例化,可能导致多个对象实例,也不要支持Icloneable接口,导致多个对象的实例,单例模式只考虑了对象创建的管理,没有考虑对象销毁的管理,支持垃圾回收的平台的对象的开销来讲,没必要对其销毁进行特殊的管理。
理解:Singleton模式核心:如何控制用户使用new对一个类的构造方法任意调用。