1. 概述

Singleton Pattren 要求一个类有且仅有一个实例,并且提供一个全局变量。这个创建的对象是独一无二的,在这个单独对象实例中,集中所创建类的所有属性和方法。
在创建一个单例,何时需要,这是程序设计的关键。从定义上可知这个类供全局调用,产品(程序)都可调用,所有是个全局静态变量,一般是不允许有派生类的。比如,火车的票数及票种,必须全局变量,这个往往是为了防止多线程调用时,导致问题溢出。

2. 模型图及思路

NET设计模式-单例模式(Singleton Pattern)

NET设计模式-单例模式(Singleton Pattern)

3. 代码实现

//单例模式类不能派生
public sealed class Singleton
{
    //静态对象,才能在静态函数中访问
    private static Singleton uniqueInstance;

    //线程安全控制实例
    static object synobj = new object();
    public static Singleton GetInstace()
    {
         //不加线程控制时,当两个线程同时运行GetInstance方法时,此时两个线程判断(uniqueInstance ==null)这个条件时都返回真,此时两个线程就都会创建Singleton的实例
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
        lock(synobj)
        {
            // 如果类的实例不存在则创建,否则直接返回
             //为创建实例时,进行创建
           if (uniqueInstance == null)
           {
                uniqueInstance = new Singleton();
           }
      }
        return uniqueInstance;
    }

    //私有构造函数,只允许在此类中创建对象
    private Singleton()
    {
    }

}
View Code

 

以上的设计确实解决多线程的问题,但是上面的代码对于每个线程辅助对象locker枷锁后,在判断实例时候存在,对于这个操作完全没必要。可以当地一个线程创建实例后,后面的线程只需要直接判断是否为null。就如一下的代码。

//单例模式类不能派生
public sealed class Singleton
{
    //静态对象,才能在静态函数中访问
    private static Singleton uniqueInstance;

    //线程安全控制实例
    static object synobj = new object();
    public static Singleton GetInstace()
    {
         //不加线程控制时,当两个线程同时运行GetInstance方法时,此时两个线程判断(uniqueInstance ==null)这个条件时都返回真,此时两个线程就都会创建Singleton的实例
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁" 
            //只需要家这句判断就可以了
      if(uniqueInstance == null)
       {
        lock(synobj)
        {
            // 如果类的实例不存在则创建,否则直接返回
             //为创建实例时,进行创建
           if (uniqueInstance == null)
           {
                uniqueInstance = new Singleton();
           }
      }
     }
        return uniqueInstance;
    }

    //私有构造函数,只允许在此类中创建对象
    private Singleton()
    {
    }

}
View Code

相关文章: