饿汉实现方式和懒汉实现方式
饿汉方式实现单例模式
template <typename T>
class Singleton {
static T data;
public:
static T* GetInstance() {
return &data;
}
};
只要通过 Singleton 这个包装类来使用 T 对象, 则一个进程中只有一个 T 对象的实例.
懒汉方式实现单例模式
懒汉方式最核心的思想是 “延时加载”. 从而能够优化服务器的启动速度.
template <typename T>
class Singleton {
static T* inst;
public:
static T* GetInstance() {
if (inst == NULL) {
inst = new T();
}
return inst;
}
};
- 存在一个严重的问题, 线程不安全.
- 第一次调用 GetInstance 的时候, 如果两个线程同时调用, 可能会创建出两份 T 对象的实例.
- 但是后续再次调用, 就没有问题了.
懒汉方式实现单例模式(线程安全版本)
template <typename T>
class Singleton {
volatile static T* inst;//防止编译器优化
static std::mutex lock;
public:
static T* GetInstance() {
if (inst == NULL) {//双重判定降低冲突的概率,提高性能
lock.lock();
if(inst==NULL){
inst = new T();
}
lock.unlock();
}
return inst;
}
};
注意
- 加锁解锁的位置
- 双重if判断,避免不必要的锁竞争
- volatile关键字防止过度优化