码迷,mamicode.com
首页 > 其他好文 > 详细

“只生一个娃”--设计模式中的单例模式

时间:2015-07-26 22:40:06      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:设计模式   singleton   单例模式   

“只生一个娃”–设计模式中的单例模式(Singleton)

  • 引言
    ??被人问到什么是单例模式,突然回答不上来,似乎印象不深了。回去补了一下功课,突然明白了,原来在项目中一直使用的日志模块即采用了单例模式,只是熟视无睹,没有意识到罢了。
    ??所谓单例模式(Singleton),即指一个类只有一个实例(Instance),并给外界提供访问该实例的一个全局访问点。
    ??通常我们可以使用全局变量的方式来实现“只生一个娃”,但更好的方法就是:让该类自身负责创建和保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且对外提供一个访问该实例的方法。下面我们看一下具体实现。

  • 单例模式实现
    ??定义一个Singleton类,添加一个静态方法GetInstance,负责创建自己的唯一实例,并供客户端访问。

class Singleton  
{  
private:  
    Singleton()  
    {  
    }  
    static Singleton *m_pInstance;  

public:  
    static Singleton * GetInstance()  
    {  
        if(m_pInstance == NULL)  //若不存在,则new一个新的实例。  
                m_pInstance = new Singleton();  
        return m_pInstance;  
    }

    //可以定义一个具体干活的方法
    void DoWork()
    {
        printf("the work is done!");   
    }  
}; 

??注意:构造函数设为private,这样外界就不能通过new操作符来实例化该类。
??客户端访问方法:

Singleton* p1 = Singleton :: GetInstance();
Singleton* p2 = p1->GetInstance();
Singleton & ref = * Singleton :: GetInstance();

p1->DoWork();
p2->DoWork();
ref.DoWork();
Singleton :: GetInstance()->DoWork();
  • 问题讨论
    多线程环境下,如果多个线程同时访问Singleton类的GetInstance方法,则有可能造成创建多个实例。因此应该进行加锁保护,可以使用lock机制,确保当一个线程位于代码的临界区时,另一个线程如果访问可被阻塞等待,不进入临界区。可以这样来实现:
class Singleton  
{  
private:  
    Singleton()  
    {  
    }  
    static Singleton *m_pInstance;
    CCriticalSection m_cs;   //定义一个临界区对象
public:  
    static Singleton * GetInstance()  
    {  
        if(NULL == m_pInstance)  //若不存在,则new一个新的实例。  
        {
            lock(m_cs)         //尽在实例未被创建时进行加锁处理
          {
              if(NULL == m_pInstance) //二次判断
              {
                     m_pInstance = new Singleton();  
              }  
          }
        }
        return m_pInstance;  
    }

    //可以定义一个具体干活的方法
    void DoWork()
    {
        printf("the work is done!");   
    }  
}; 

??注意:为什么要二次判断呢?
??第一次NULL == m_pInstance判断是为了避免每次都要加锁,能够提高效率;
??第二次判断是因为:如果实例未被创建,两个线程同时通过第一层NULL == m_pInstance判断,由于lock机制,只有第一个线程进入,另一个排队等候,如果第一个线程创建了实例并出来后,第二个线程进入后还是可以创建新的实例的。

??由此可见:想要保证只生一个小孩真是要时时留意、处处留心,安全措施要绝对保证啊 O(∩_∩)O.

版权声明:本文为csdn博主[applebite](http://blog.csdn.net/applebite)原创文章,转载请注明出处,侵权必究。

“只生一个娃”--设计模式中的单例模式

标签:设计模式   singleton   单例模式   

原文地址:http://blog.csdn.net/applebite/article/details/47072603

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!