一、介绍
单件模式要求一个类有且只有一个实例,并且提供一个全局访问点。
例如:团购网上,商品库存问题,为了促进广告效益,常常会拿一些商品,比如说库存为10,以低价出售,然后竞拍的用户几乎是百万来计。但是商品库存是有限的。所以此时需要定义一个全局的访问点,且实例只有一个,每成功接收一个订单,库存减1。
二、实现
I、简单实现
View Code
//Singleton简单实现 public sealed class SimpleSingleton { static SimpleSingleton instance = null; private SimpleSingleton() { } public static SimpleSingleton Instance { get { if (instance==null) { instance = new SimpleSingleton(); } return instance; } } }
这种实现方法对线程来说并不是安全的,来我们的示例来说,用户是百万级的,存在两个线程中,同时判断instance==null为真的概率是非常大的,这时会同时创建两个实例,造成的结果:库存量错乱。本来只是拿10件商品来促销,但却接收到了11个订单。
II、线程安全
View Code
//安全的线程 public sealed class SecureSingleton { static SecureSingleton instance = null; static readonly object obj=new object(); private SecureSingleton(){} public static SecureSingleton Instance { get { lock (obj) { if (instance == null) { instance = new SecureSingleton(); } return instance; } } } }
这种实现方法对线程是安全的,我们首先建立个辅助对象,第一个线程进入后,先对辅助对象加锁,后判断对象是否存在,不存在则创建.如第一个线程进来后,还未释放锁,此时第二个线程进来,会判断,辅助对象不是加了锁,如加了锁则等待释放。这样就不会实例化多个对象。不过此时性能有所损失。
III、双重锁定(以前一直以为是双锁,其实是双重判断+锁定)
View Code
//双重锁定(以前一直以为是双锁,其实是双重判断+锁定) public sealed class DoubleSingleton { static DoubleSingleton instance = null; static readonly object obj = new object(); private DoubleSingleton() { } public static DoubleSingleton Instance { get { if (instance == null) { lock (obj) { if (instance == null) { instance = new DoubleSingleton(); } } } return instance; } } }
对于线程是安全的,同时又不用每次判断辅助对象是否加了锁,提高了性能。
IV、静态初始化
View Code
//静态初始化 public sealed class StaticSingleton { static StaticSingleton instance = null; private StaticSingleton() { } public static StaticSingleton Instance { get { return instance; } } }
编译时发生,.net 中单件的首选方法。缺点:实例化机制的控制权较少
V、延迟初始化
View Code
//延迟初始化 public sealed class DelaySingleton { public static DelaySingleton Instance { get { return Intance.instance; } } } //延迟对象 class Intance { static Intance() { } public static readonly DelaySingleton instance = new DelaySingleton(); }
弥补了静态初始化的缺点