廢話不多說,常用的程式碼積澱下來。
一、懶漢模式:即第一次呼叫該類例項的時候才產生一個新的該類例項,並在以後僅返回此例項。
需要用鎖,來保證其執行緒安全性:原因:多個執行緒可能進入判斷是否已經存在例項的if語句,從而non thread safety。
使用double-check來保證thread safety。但是如果處理大量資料時,該鎖才成為嚴重的效能瓶頸。
1、靜態成員例項的懶漢模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Singleton { private: static Singleton* m_instance; Singleton(){} public: static Singleton* getInstance(); }; Singleton* Singleton::getInstance() { if(NULL == m_instance) { Lock();//借用其它類來實現,如boost if(NULL == m_instance) { m_instance = new Singleton; } UnLock(); } return m_instance; } |
2、內部靜態例項的懶漢模式
這裡需要注意的是,C++0X以後,要求編譯器保證內部靜態變數的執行緒安全性,可以不加鎖。但C++ 0X以前,仍需要加鎖。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class SingletonInside { private: SingletonInside(){} public: static SingletonInside* getInstance() { Lock(); // not needed after C++0x static SingletonInside instance; UnLock(); // not needed after C++0x return instance; } }; |
二、餓漢模式:即無論是否呼叫該類的例項,在程式開始時就會產生一個該類的例項,並在以後僅返回此例項。
由靜態初始化例項保證其執行緒安全性,WHY?因為靜態例項初始化在程式開始時進入主函式之前就由主執行緒以單執行緒方式完成了初始化,不必擔心多執行緒問題。
故在效能需求較高時,應使用這種模式,避免頻繁的鎖爭奪。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class SingletonStatic { private: static const SingletonStatic* m_instance; SingletonStatic(){} public: static const SingletonStatic* getInstance() { return m_instance; } }; //外部初始化 before invoke main const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic; |
(完)