线程安全单例模式

#include <memory>

#include <mutex>

namespace sdk_mobile{

/*

///单例模式, 多线程安全

///< 1. 饿汉方式,  使用全局静态变量,在程序启动时完成构建工作,

///<    线程安全, 但会减慢启动速度,同时在没有使用是内存已经创建

// template<class T>

class Singleton_1{

public:

    static Singleton_1& instance(){

        return *instance_;

    }

    static void destoryInstance(){

        if(instance_ != nullptr){

            delete instance_;

        }

    }

private:

    Singleton_1() = default;

    Singleton_1(const Singleton_1& ) = delete;

    Singleton_1& operator=(const Singleton_1&) = delete;


    static Singleton_1* instance_;

};

Singleton_1* Singleton_1::instance_ = new Singleton_1();

///< 2.懒汉方式: 线程不安全 ----> Double-Checked Locking Pattern

///< a. instance_ = new Singleton_2(): 此句代码会执行三件事:1.申请一块内存, 2.调用构造函数, 3.将内存地址赋值给instance_

///<    见: a1, a2

///< b. 采用std::unique_ptr 解决释放问题

class Singleton_2{

public:

    static Singleton_2& instance(){

        if(instance_ == nullptr){  ///a1 : 多线程读, 可能在a2 的步骤没有执行完, 访问了, 读取了, 调用了, 出现问题了

            std::lock_guard<std::mutex> lock(mutex_);

            if(instance_ == nullptr){  ///a2 : 持有线程写, 写分为三步, 可能是乱序,

                instance_.reset(new Singleton_2);

            }

        }

        return *instance_;

    }

    ~Singleton_2() = default;

private:

    Singleton_2() = default;

    Singleton_2(const Singleton_2& ) = delete;

    Singleton_2& operator=(const Singleton_2&) = delete;


    static std::unique_ptr<Singleton_2> instance_;

    static std::mutex mutex_;

};

std::unique_ptr<Singleton_2> Singleton_2::instance_ = nullptr;

std::mutex Singleton_2::mutex_;

///< 3. 懒汉方式,采用静态变量实现

class Singleton_3{

public:

    static Singleton_3& instance(){

        static Singleton_3 instance_;

        return instance_;

    }

    ~Singleton_3() = default;

private:

    Singleton_3() = default;

    Singleton_3(const Singleton_3& ) = delete;

    Singleton_3& operator=(const Singleton_3&) = delete;

};

*/

///< 4. 采用std::call_once ,线程安全

template <class T>

class Singleton{

public:

    static T& instance(){

        static std::once_flag s_flag;

        std::call_once(s_flag, [&]{

            instance_ = std::unique_ptr<T>(new T);

        });

        return *instance_;

    }

protected:

    Singleton() = default;

    ~Singleton() = default;


private:

    ///< delete 直接将object file文件中的符号删除

    Singleton(const T&) = delete;

    Singleton& operator= (const T& ) = delete;

    static std::unique_ptr<T> instance_;

};

template <class T>

std::unique_ptr<T> Singleton<T>::instance_ = nullptr;

}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容