一、懶漢模式:即第一次調用該類實例的時候才產生一個新的該類實例,並在以後僅返回此實例。
需要用鎖,來保證其線程安全性:原因:多個線程可能進入判斷是否已經存在實例的if語句,從而non thread safety.
使用double-check來保證thread safety.但是如果處理大量數據時,該鎖才成爲嚴重的性能瓶頸。
1、靜態成員實例的懶漢模式:
2、內部靜態實例的懶漢模式
這裏需要注意的是,C++0X以後,要求編譯器保證內部靜態變量的線程安全性,可以不加鎖。但C++ 0X以前,仍需要加鎖。
二、餓漢模式:即無論是否調用該類的實例,在程序開始時就會產生一個該類的實例,並在以後僅返回此實例。
由靜態初始化實例保證其線程安全性,WHY?因爲靜態實例初始化在程序開始時進入主函數之前就由主線程以單線程方式完成了初始化,不必擔心多線程問題。
故在性能需求較高時,應使用這種模式,避免頻繁的鎖爭奪。
- #include <iostream>>
- using namespace std;
- class Singleton
- {
- public:
- static Singleton *GetInstance();
- private:
- Singleton()
- {
- cout << "Singleton ctor" << endl;
- }
- ~Singleton()
- {
- cout << "Singleton dtor" << endl;
- }
- static Singleton *m_pInstance;
- class Garbo
- {
- public:
- ~Garbo()
- {
- if (Singleton::m_pInstance)
- {
- cout << "Garbo dtor" << endl;
- delete Singleton::m_pInstance;
- }
- }
- };
- static Garbo garbo;
- };
- Singleton::Garbo Singleton::garbo; // 一定要初始化,不然程序結束時不會析構garbo
- Singleton *Singleton::m_pInstance = NULL;
- Singleton *Singleton::GetInstance()
- {
- if (m_pInstance == NULL)
- m_pInstance = new Singleton;
- return m_pInstance;
- }
- int main()
- {
- Singleton *p1 = Singleton::GetInstance();
- Singleton *p2 = Singleton::GetInstance();
- if (p1 == p2)
- cout << "p1 == p2" << endl;
- return 0;
- }
輸出結果如下:
Singleton ctor
p1 == p2
Garbo dtor
Singleton dtor