单例模式,顾名思义,就是保证在整个应用程序的生命周期中,某对象无论被调用多少次,只被创建一个实例,那么我们要如何实现这种模式呢?
第一种方式,饿汉模式,即在该对象加载时就创建实例,这样是最简单,也不用担心多线程下被多次创建的问题,因为这种模式下,线程安全性由CLR来解决,实现代码如下:
public class Sys_FormIDIdentityMap
{
private static readonly Sys_FormIDIdentityMap sys_FormIDIdentityMapInstance = new Sys_FormIDIdentityMap();
private Sys_FormIDIdentityMap() { }
public static Sys_FormIDIdentityMap GetInstance()
{
return sys_FormIDIdentityMapInstance;
}
}
解释下上面代码:单例模式中,我们必须要设置一个静态的类对象,以保证后期调用都可以直接访问这个静态类对象,而不用实例化该类。同时我们必须将该类的构造函数设置为私用的,要不然在程序员在调用时又可以重新实例化类的话,也就不存在单例的意义了。
饿汉模式有一个缺点,就是不管你要不要用,在应用程序启动时,就已经初始化好了,这样如果单例模式应用的多了,就会造成启动慢的问题。
第二种式,懒加载模式,即lazy模式,实现代码如下:
public class Sys_FormIDIdentityMap
{
private static Sys_FormIDIdentityMap sys_FormIDIdentityMapInstance = null;
private static readonly object SynObject = new object();
private Sys_FormIDIdentityMap() { }
public static Sys_FormIDIdentityMap GetInstance()
{
if (sys_FormIDIdentityMapInstance == null)
{
lock (SynObject)
{
if (sys_FormIDIdentityMapInstance == null)
{
sys_FormIDIdentityMapInstance = new Sys_FormIDIdentityMap();
}
}
}
return sys_FormIDIdentityMapInstance;
}
}
同样解释一下上面代码:
SynObject为辅助只读静态对象,lock(SynObject)用于保证代码运行到该处时阻止另一个进程访问后面的代码,至到当前进程运行完成(即释放当前锁),主要目点是为了阻止多个进程同时访问sys_FormIDIdentityMapInstance,且sys_FormIDIdentityMapInstance为null时造成初始化多个sys_FormIDIdentityMapInstance对象,从而失去了单例模式的意义。
代码中的两个 if (sys_FormIDIdentityMapInstance == null)解释:
第一个判断保证只有sys_FormIDIdentityMapInstance==null时,才进行锁操作,这样可以减少因为锁而影响系统性能的和减少额外的开销。
第二个判断保证只有sys_FormIDIdentityMapInstance==null时,才实例化sys_FormIDIdentityMapInstance对像,这样可以保证整个应用程序的生命周期中只有一个sys_FormIDIdentityMapInstance对象。两个if判断,就是经典的Double-Checked Locking设计。