您的位置:首页 > 其它

单例模式详解

2016-03-07 16:55 190 查看
           设计模式——单例模式

        创建型设计模式一共包括五类设计模式,分别是:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。上篇博客中讲到了工厂方法模式,这篇博客就给大家说一下经常用到的单例模式。

单例模式:

    定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    结构图:

   

         单例模式中就只有这一个类,Singleton类,他的作用是:定义一个GetIntance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例。代码如下:

  

class Singleton
{
private static Singleton instace;
private Singleton ()
{
}
public static Singleton GetInstance()
{
if (instace ==null)     //判断是否实例化
{
instace = new Singleton();
}
return instace;
}
}


    使用单例模式的好处:单例模式因为Singleton封装它的唯一实例,这样它可以严格的控制客户怎样访问它以及何时访问它,简单的说就是对唯一实例的受控访问。

多线程的单例:

     如果在多线程的程序中,多个线程同时访问Singleton类,调用getInstance方法,会有可能创建多个实例的,所以在这里要在程序中加上一把锁:Lock。Lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区,如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止)直到对象被释放。代码如下:   

class Singleton
{
private static Singleton instace;
private static readonly object syncRoot = new object();    //程序运行时创建一个静态只读的进程辅助对象。
private Singleton ()
{

}
public static Singleton GetInstance()
{
lock (syncRoot )   //在同一时刻加了锁的那部分程序只有一个线程可以进入。
{
if (instace == null)  //判断是否实例化
{
instace = new Singleton();

}
return instace;
}

}
}


      这样可以使得实例对象由最先进入的那个线程创建,以后的线程在进入时不会再去创建对象实例了,由于有了lock,就保证了多线程环境下的同时访问也不会造成多个实例的生成。但是这样的的锁定有一个弊端,就是在每次调用GetInstance时就需要进行一次锁定lock。这样会无形中影响了程序的性能。所以为了解决这个问题,有了下边的双重锁定:

    双重锁定不用让线程每次都加锁,而只是在实例未被创建的时候在加锁处理,同时也能保证多线程的安全。代码如下:

class Singleton
{
private static Singleton instace;
private static readonly object syncRoot = new object();    //程序运行时创建一个静态只读的进程辅助对象。
private Singleton ()
{

}
public static Singleton GetInstance()
{
if (instace ==null)    //第一次判断是否实例化
{
lock (syncRoot)   //在同一时刻加了锁的那部分程序只有一个线程可以进入。
{
if (instace == null)      <span style="font-family: Arial, Helvetica, sans-serif;">//第一次判断是否实例化</span>

{
instace = new Singleton();
}
}
}
return instace;
}
}<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>


     为什么叫双重锁定?因为在对于instance存在的情况下,就直接返回,这样就没有问题,当instance为null并且同时有两个线程同时调用GetInstance()方法时,他们将都可以通过第一重instance==null的判断。然后由于lock机制,这两个线程则只有一个进入,另一个在外排队等候。此时如果没有了第二重的instance判断,则第一个线程创建了实例,而第二个线程还是可以在继续创建新的实例的。

    单例模式是一个很常见的模式,以后我们在做系统的时候回经常用到,好好总结一下,以后用的时候就知道怎么用了。

     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: