Singleton单件 (创建型模式)

模式分类

从目的来看:

--创建型模式: 负责对象创建。

--结构型模式:处理类与对象间的组合。

--行为型模式: 类与对象交互中的职责分配。

从范围来看:

--类模式处理类与子类的静态关系。

--对象模式处理对象间的动态关系。

动机: 如果绕过常规的构造器,提供一种机制来保证一个类只能有一个实例。

实例如下:

public class Singleton

 {

    private static Singleton instance;

     //思想如下:我不能让用户实例化该类,因为,如果我让用户实例化,用户就可以实例化很多实例。

    private Singleton(){}

     //怎么办呢?我想到,可以这样对外提供一个方法,或者属性,该方法判断,只能实例化一次

    public static Singleton Instance

    {

          get

          {

                if ( instance == null)

                {

                      instance = new Singleton();

                 }

                 return instance;

           }

     }

}

上面的这个类,不能应对多线程环境:在多线程环境下,使用上面Singleton模式仍然有可能得到Singleton类的多个实例对象。

那么怎么才适应多线程的环境呢?

public  class Singleton

{

      private static volatile Singleton instance;    //volatile关键字保证编译器不会对该代码进行微调,保证正确性,保证实例的唯一性

      //想了想应该要用到锁,通过锁,然后在里面判断是否实例化过,见如下代码

      private static object  lockHeper = new object();

      public static Singleton Instance

      {

          get

          {

                if ( instance == null)    //如果是多线程,可能会有这样一个情况,第一个线程判断等于空,还没来的急实例化,第二个线程进来了,也判断为空,这就有可能会有

                {                                //两个实例,也有这样的一个可能,第一个刚刚实例化完,然后解锁,第二个进来了,如果实例化的化,也会产生两个实例,看下面如何解决

                      lock(lockHeper )

                      { 

                         if(instance == null)     //解决方法就是在判断一次是否为空,也就是所谓的双锁

                         {

                             instance = new Singleton();

                         }

                      }

                 }

                 return instance;

           }

      }

}

以下还有一些方法也可以完成多线程的单例模式 ,有一个弊端就是不支持参数化

public  class Singleton

{

     public static readonly Singleton instance = new Singleton();

     private Singleton(){}

}

//上面这个代码怎么理解呢?它的原理如下

public class Singleton

{

   public static readonly Singleton instance;  //对静态字段的赋值前,首先系统会实例化一个静态的构造函数

   static Singleton()     //在多线程环境下,只有一个线程执行静态构造器,所以他只有一份,这样就保证了他的唯一性,静态构造器必须是无参的,并且只能有一个静态构造器

   {

      instance = new Singleton();  然后在构造函数内,为静态字段赋值     

   } 

   pirvate Singleton(){}

}

模式代码,没有固定,只要能达到效果,就是该模式,比较灵活!这个模式主要是对实例个数的控制

Singleton模式的核心是"如何控制用户使用new对一个类的实例构造器的任意调用"

      

原文地址:https://www.cnblogs.com/blosaa/p/2203426.html