C++的單例模式與線程安全單例模式(懶漢/餓漢)

參考:C++的單例模式與線程安全單例模式(懶漢/餓漢)
1 教科書裏的單例模式
我們都很清楚一個簡單的單例模式該怎樣去實現:構造函數聲明爲private防止被外部函數實例化,內部保存一個private static的類指針保存唯一的實例,實例的動作由一個public的類方法代勞,該方法也返回單例類唯一的實例。
代碼:

class CSingleton
{  
private:
    CSingleton(){}
    static CSingleton* m_Instance;
public:
    static CSingleton* instance(){
        if (m_Instance == NULL)
            m_Instance = new singleton();
        return m_Instance;
    }
};

2 懶漢與餓漢
單例大約有兩種實現方法:懶漢與餓漢。

  • 懶漢:故名思義,不到萬不得已就不會去實例化類,也就是說在第一次用到類實例的時候纔會去實例化,所以上邊的經典方法被歸爲懶漢實現;
  • 餓漢:餓了肯定要飢不擇食。所以在單例類定義的時候就進行實例化。

特點與選擇:

  • 由於要進行線程同步,所以在訪問量比較大,或者可能訪問的線程比較多時,採用餓漢實現,可以實現更好的性能。這是以空間換時間。
  • 在訪問量較小時,採用懶漢實現。這是以時間換空間。

3 線程安全的懶漢實現
線程不安全,怎麼辦呢?最直觀的方法:加鎖。

  • 加鎖的經典懶漢實現:
class Singleton
{
private:
    Singleton(){}
    static Singleton* m_Instance;
public:
    static pthread_mutex_t mutex;
    static Singleton* initance();
};

pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
Singleton* Singleton::m_Instance = NULL;
Singleton* Singleton::initance()
{
    if (NULL == m_Instance)
    {
        pthread_mutex_lock(&mutex);
        if (NULL == m_Instance)
            m_Instance = new Singleton();
        pthread_mutex_unlock(&mutex);
    }
    return m_Instance;
}

4 餓漢實現
因爲餓漢實現本來就是線程安全的,不用加鎖。

class CSingleton{
private:
    CSingleton(){}
    static CSingleton* m_Instance;

public:
    static CSingleton* getInstance(){
        return m_Instance;
    }
};
//create m_Instance
CSingleton* CSingleton::m_Instance = new CSingleton();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章