单例模式
懒汉式
#include <thread>
#include <cstdio>
class Singleton
{
private:
Singleton(){printf("new Singleton.\n");};
static Singleton* m_Instance;
public:
static Singleton* GetInstance()
{
if(m_Instance==nullptr)
{
if(m_Instance == nullptr)
{
m_Instance = new Singleton();
}
}
return m_Instance;
}
};
Singleton* Singleton::m_Instance = nullptr;
void func()
{
Singleton *s = Singleton::GetInstance();
}
int main()
{
std::thread t1(func);
std::thread t2(func);
t1.join();
t2.join();
}
可以看到上面的代码是线程不安全的:
如果两个线程同时调用GetInstance方法且同时检测到Instance是NULL,则两个线程会同时构造一个实例给Instance,这样就发生错误。
懒汉式-上锁
#include <thread>
#include <mutex>
#include <cstdio>
std::mutex mylock;
class Singleton
{
private:
Singleton(){printf("new Singleton.\n");};
static Singleton* m_Instance;
public:
static Singleton* GetInstance()
{
if(m_Instance==nullptr)
{
mylock.lock();
if(m_Instance == nullptr)
{
m_Instance = new Singleton();
}
mylock.unlock();
}
return m_Instance;
}
};
Singleton* Singleton::m_Instance = nullptr;
void func()
{
Singleton *s = Singleton::GetInstance();
}
int main()
{
std::thread t1(func);
std::thread t2(func);
t1.join();
t2.join();
}
饿汉式
饿汉式一开始就创建了类的实例,所以直接将创建好的实例返回就好。
#include <cstdio>
class Singleton
{
private:
/* data */
Singleton(){printf("New Singleton.\n");};
public:
static Singleton* GetInstance()
{
static Singleton m_Instance;
return &m_Instance;
}
};
int main()
{
Singleton* m_Instance = Singleton::GetInstance();
return 0;
}