[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 函數裏定義一個靜態的實例,也可以保證擁有唯一實例,在返回時只需要返回其指針。

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