C#设计模式--单例模式

单例模式(创建型):

单件、单例、SingleTon
 
一、经典模式:
publicclassSingleton
{
privatestaticSingleton instance; //私有的、静态的 变量
privateSingleton() //私有的构造函数
{
}
publicstaticSingletonGetInstance() //全局访问
{
if(instance==null) //未实例化
{
instance=newSingleton(); //创建一个实例
}
return instance; //实例化过,返回实例
}
}

解析如下:

  1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的;

  2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量instance来保存该类的唯一实例;

  3)必须提供一个全局函数访问获得该实例,并且在该函数提供控制实例数量的功能,即通过if语句判断instance是否已被实例化,如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。

  在这种经典模式下,没有考虑线程并发获取实例问题,即可能出现两个线程同时获取instance实例,且此时其为null时,就会出现两个线程分别创建了instance,违反了单例规则。因此,需对上面代码修改。

 

二、多线程下的单例模式

1、懒汉模式

 

publicclassSingleton
{
privatestaticSingleton instance;
privatestaticobject _lock=newobject();
privateSingleton()
{
}
publicstaticSingletonGetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=newSingleton();
}
}
}
return instance;
}
}

 

上述代码使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。

 

2、饿汉模式

  这种模式的特点是自己主动实例。

publicsealedclassSingleton
{
privatestaticreadonlySingleton instance=newSingleton(); //readonly只读的
privateSingleton()
{
}
publicstaticSingletonGetInstance()
{
return instance;
}
}

 

上面使用的readonly关键可以跟static一起使用,用于指定该常量是类别级的,它的初始化交由静态构造函数实现,并可以在运行时编译。在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用GetInstance()后才实例化出唯一的单例对象。
 
 



posted @ 2016-08-01 10:30  Eam  阅读(298)  评论(0编辑  收藏  举报