饿汉方式
template<class T>
class Singletion
{
public:
static T *GetInstance()
{
return &data;
}
private:
static T data;
}
只要通过Singletion这个包装类来使用T对象,则进程中只有一个T对象实例
懒汉方式
template<class T>
class Singletion
{
public:
static T *GetInstance()
{
if(inst == NULL)
inst = new T();
return inst;
}
private:
static T *inst;
}
存在问题:线程不安全,第一次 调用GetInstance时,如果两个线程同时调用,则会创建出两份T对象的实例
懒汉方式(线程安全版本)
class Singletion
{
public:
static T* GetInstance()
{
if(inst == NULL)
{
lock.lock();
if(inst == NULL)
inst = new T();
lock.unlock();
}
return inst;
}
private:
volatile static T* inst;
static std::mutex lock;
}
注意:
- 加锁解锁的位置
- 双重if判定,避免不必要的锁竞争
- volatile关键字防止编译器过度优化(每次读取元素从内存读取,保证内存可见性)