单例模式的一个官方定义:确保一个类只有一个实例,并提供一个全局访问点。
根据单例模式的概念和上面的类图,总结了单例模式的以下三个要点:
<!–[if !supportLists]–>1. <!–[endif]–>定义私有的构造函数。一旦定义了私有的构造函数,在外界就不能通过new来创建它的实例了。因此能确保一个类只有一个实例。
<!–[if !supportLists]–>2. <!–[endif]–>要创建实例,就要有一个变量来保存该实例。因此需要定义静态私有变量来记录该类的唯一实例。
<!–[if !supportLists]–>3. <!–[endif]–>定义一个公有方法或者属性来把该类的实例公开出去。也就是需要提供类的全局访问点。
若考虑线程并发问题,当出现两个或更多的线程同时获取instance实例,而且是null的时候,那样就是多个线程分别创建了instance,这是违反单例模式的规则的。因此,考虑了多线程后,代码如下:
public class Singleton
{
private static Singleton instance;
private static object _lock=new object();
private Singleton()
{
}
public static Singleton GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}
程序中采用了“双重锁”方式,有效地解决了单例模式在多线程下的问题。程序用了内外两层if语句:内层if语句块的加锁操作保证了只有一个线程可以访问该语句块,即只创建一个实例。外层if语句块先判断instance实例是否为空,这样每个线程不用每次都加锁,只有实例为空才加锁并创建实例。如果已经存在instance实例,就直接返回该实例,提高了程序的性能。