单例模式下的线程安全

2017-08-08  本文已影响0人  fertilizer

首先我们回顾一下,单例模式的概念:
单例模式:自我创建对象,唯一实例。
关键点:构造函数是私有的。

主要分为两种方式:lazy 和 hungry。
lazy方式主要是当生成该类实例时才调用,按需调用。(好像是有个专业术语:延迟初始化
hungry方式则是当类定义时就已经在静态存储区里生成该实例了

//case 1
class lazySingleton {
public:
    static lazySingleton* get_instance();
private:
    static lazySingleton* instance;
    lazySingleton();
};
lazySingleton::lazySingleton() = default;
lazySingleton* lazySingleton::instance = nullptr;
static lazySingleton* lazySingleton::get_instance() {
    if (instance == nullptr) {
        instance = new lazySingleton();
    }
    return instance;
}
//case 2
class hungrySingleton {
public:
    static hungrySingleton* get_instance();
private:
    static hungrySingleton* instance;
    hungrySingleton();
};
hungrySingleton::hungrySingleton() = default;
hungrySingleton* hungrySingleton::instance = new hungrySingleton();
static hungrySingleton* hungrySingleton::get_instance() {
    return instance;
}

case2很明显线程安全,case1则不是线程安全的。

case1改进的方法就是在get_instance()上加锁。但是立即加锁不作任何状态的检查很浪费资源,所以就有双重检测锁。大致代码如下:

static Singleton& Instance()  
{
    if (instance_ == NULL) 
    {
        Lock lock; //基于作用域的加锁,超出作用域,自动调用析构函数解锁
        if (instance_ == NULL)
        {
              instance_ = new Singleton;
        }
    }
    return *instance_;
}

除了以上三种,effective c++中的则是利用了local-static对象使得只有首次调用才会创建实例这一特性保证不会多次创建实例。
先总结这么多,下次补充具体实现代码。赶紧找食,超市要关门了~~~~

上一篇下一篇

猜你喜欢

热点阅读