完美的單例模式是線程安全的铺董,使用懶漢模式。
Lock類用于加鎖解鎖禀晓,Singleton類為單例類精续。
不過還可能出現(xiàn)問題坝锰,因為CPU可能亂序執(zhí)行,會出現(xiàn)未定義行為導(dǎo)致段錯誤:
假如線程A進入鎖內(nèi)并分配對象的空間重付,但是由于指令可能亂序什黑,實際上導(dǎo)致local_instance被先指向一塊未被分配的內(nèi)存,然后再在這塊內(nèi)存上進程初始化堪夭。但是在指向后愕把,未初始化前,另一線程B可能通過getInstance獲取到這個指針森爽。
#include <iostream>
#include <mutex>
using namespace std;
class Lock
{
private:
mutex mtx;
public:
void lock(){mtx.lock();}
void unlock(){mtx.unlock();}
};
class Singleton
{
private:
Singleton(){};
static Lock* locker;//靜態(tài)鎖對象指針
static Singleton* instance;//靜態(tài)單例對象指針
public:
static Singleton* getInstance()
{
if(!instance)
{
locker->lock();
if(!instance)
{
instance = new Singleton;
}
locker->unlock();
}
return instance;
};
};
// 初始化鎖
Lock* Singleton::locker = new Lock();
// 初始化單例
Singleton* Singleton::instance = 0;
int main()
{
Singleton *s1 = Singleton::getInstance();
Singleton *s2 = Singleton::getInstance();
cout << s1 << endl;
cout << s2 << endl;
return 0;
}