這是從公司內網上轉過來的,總結的不錯,就記錄了,這裏默默感謝下。
一、即第一次調用該類實例的時候才產生一個新的該類實例,並在以後僅返回此實例。
需要用鎖,來保證其線程安全性:原因:多個線程可能進入判斷是否已經存在實例的if語句,從而non thread safety.
使用double-check來保證thread safety.但是如果處理大量數據時,該鎖才成爲嚴重的性能瓶頸。
1、靜態成員實例:
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以前,仍需要加鎖。
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?因爲靜態實例初始化在程序開始時進入主函數之前就由主線程以單線程方式完成了初始化,不必擔心多線程問題。
故在性能需求較高時,應使用這種模式,避免頻繁的鎖爭奪。
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;
完。