鼠扑 发表于 2024-8-12 22:33:24

设计模式——单例模式

什么是单例模式

一个类只能创建一个对象,即单例模式,该模式下可包管系统中该类只有一个实例,并提供一个访问它的全局接口,该实例被所有程序模块共享。
单例模式有两种实例环境



[*]饿汉模式:程序启动就创建一个唯一的实例对象
[*]懒汉模式:调佣全局接口的时候创建唯一的实例。
饿汉模式

class Singleton
{
public:
        static Singleton* GetInstance()
        {
                return _ins;
        }

        void Add(const string& str)
        {
                _mtx.lock();

                _v.push_back(str);

                _mtx.unlock();
        }

        void Print()
        {
                _mtx.lock();

                for (auto& e : _v)
                {
                        cout << e << endl;
                }
                cout << endl;

                _mtx.unlock();
        }

private:
        //限制类外随意创建对象
        Singleton()
        {

        }

private:
        int _n;
        vector<string> _v;
        mutex _mtx;

        static Singleton* _ins;
};

Singleton* Singleton::_ins = new Singleton;
但是饿汉有一个题目:如果单例对象非常耗时或者占用很多资源,好比加载插件,初始化网络毗连,也有大概在程序一开始用不到,那么在程序一开始创建就会导致程序启动很慢,所以有了懒汉模式。
懒汉模式

class Singleton
{
public:
        static Singleton* GetInstance()
        {
                //双检查加锁
                if (_ins == nullptr) //提高效率,不需要每次加锁和解锁
                {
                        _imtx.lock();
                       
                        if (_ins == nullptr) //保证线程安全,只用new一次
                        {
                                _ins = new Singleton;
                        }

                        _imtx.unlock();
                }

                return _ins;
        }

        void Add(const string& str)
        {
                _vmtx.lock();

                _v.push_back(str);

                _vmtx.unlock();
        }

        void Print()
        {
                _vmtx.lock();

                for (auto& e : _v)
                {
                        cout << e << endl;
                }
                cout << endl;

                _vmtx.unlock();
        }

private:
        //限制类外随意创建对象
        Singleton()
        {

        }

private:
        int _n;
        vector<string> _v;
        mutex _vmtx;

        static mutex _imtx;
        static Singleton* _ins;
};

Singleton* Singleton::_ins = nullptr;
mutex Singleton::_imtx;
这里留意一下,创建实例的时候要用双重加锁,由于在多线程的场景下,就去一直加锁判断,要知道锁的斲丧是很大的,所以双重查抄是很紧张的。
懒汉模式的优点:



[*]第一次使用的时候创建实例对象
[*]如果多个单例对象有启动次序要求的话,也可以控制(这点饿汉模式就无法控制了)
懒汉模式的缺点



[*]复杂

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 设计模式——单例模式