[c++]单例模式及线程安全(懒汉模式 饿汉模式)

一、基础的单例模式实现

  1. 构造函数声明为 private protect ,防止被外部函数实例化;
  2. 内部保存一个 private static 的类指针保存唯一的实例;
  3. 实例的动作由一个 public 的类方法如 getInstance( ) 完成,该方法也返回单例类唯一的实例。
  • 具体实现
class singleton
{
protected:
    singleton(){}

private:
    static singleton* p;

public:
    static singleton* getInstance();

};

singleton* singleton::p = NULL;

singleton* singleton::getInstance()
{
    if (p == NULL)
        p = new singleton();
    return p;
}

看起来一切都很优雅,但是!该方法是线程不安全的,如果有两个线程同时首次调用getInstance()方法且同时检测到p是NULL值,则两个线程会同时构造一个实例给p,显然这是错误的。

 

二、懒汉模式与饿汉模式

1. 单例的两类实现方法

  • 懒汉:在第一次用到类实例的时候才会去实例化,故上边的经典方法被归为懒汉实现;
  • 饿汉:在单例类定义的时候就进行实例化

2. 特点与选择:

  • 以空间换时间:由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现。
  • 以时间换空间:在访问量较小时,采用懒汉实现。

3. 饿汉模式实现:

class singleton
{
protected:
    singleton(){}

private:
    static singleton* p;

public:
    static singleton* getInstance();

};


singleton* singleton::p = new singleton; //单例类定义的时候就进行实例化

singleton* singleton::getInstance()
{
    return p;
}

4. 线程安全的懒汉模式实现

  1. 加锁
    class singleton
    {
    protected:
        singleton()
        {
            pthread_mutex_init(&mutex);
        }
    
    private:
        static singleton* p;
    
    public:
        static pthread_mutex_t mutex;
        static singleton* getInstance();
    
    };
    
    pthread_mutex_t singleton::mutex;
    singleton* singleton::p = NULL;
    
    singleton* singleton::getInstance()
    {
        if (p == NULL)
        {
            pthread_mutex_lock(&mutex);
    
            if (p == NULL)
                p = new singleton();
    
            pthread_mutex_unlock(&mutex);
        }
        return p;
    }
    

     

  2. 内部静态变量
    class singleton
    {
    protected:
        singleton()
        {
            pthread_mutex_init(&mutex);
        }
    
    public:
        static pthread_mutex_t mutex;
        static singleton* getInstance();
    
    };
    
    
    pthread_mutex_t singleton::mutex;
    
    singleton* singleton::getInstance()
    {
        pthread_mutex_lock(&mutex);
    
        static singleton obj;
    
        pthread_mutex_unlock(&mutex);
    
        return &obj;
    }

    此方法在 getInstance 函数里定义一个静态的实例,也可以保证拥有唯一实例,在返回时只需要返回其指针。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章