单例设计模式和多线程

Posted xcantaloupe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例设计模式和多线程相关的知识,希望对你有一定的参考价值。

单例设计模式

单例:整个项目中,有某个类或者某些特殊的类,属于该类的对象只能建立一个。

#include<iostream>
using namespace std;

class MyCAS
{
private:
    MyCAS(){}

private:
    static MyCAS *m_instance;

public:
    static MyCAS *GetInstance()   ///得到对象的接口函数
    {
        if(m_instance==NULL)
        {
            m_instance = new MyCAS();
            static CGarhuishou cl;
        }
        return m_instance;
    }

    void func()
    {
        cout << "test" << endl;
    }

    class CGarhuishou  ///类中套类,释放对象
    {
    public:
        ~CGarhuishou()
        {
            if(m_instance!=NULL)
            {
                delete MyCAS::m_instance;
                MyCAS::m_instance = NULL;
            }
        }
    };
};
MyCAS *MyCAS::m_instance = NULL;

int main()
{
    MyCAS *p_a = MyCAS::GetInstance();
    p_a->func();
    return 0;
}

单例设计模式共享数据问题分析、解决

问题:需要在多个线程中创建单例类的对象,获得对象的接口函数GetInstance()要互斥,否则会导致m_instance = new MyCAS()执行多次。

static MyCAS *GetInstance()   ///得到对象的接口函数
    {
        if(m_instance==NULL)   //提高效率,防止在创建对象后还需要一直加锁。
        {
            std::unique_lock<std::mutex>mymutex(resource_mutex);
            if(m_instance==NULL)
            {
                m_instance = new MyCAS();
                static CGarhuishou cl;
            }
        }
        return m_instance;
    }

std::call_one();

call_one功能:保证函数只执行一次

std::once_flag g_flag;  ///系统定义的标记;
class MyCAS
{
    /*
    ...
    */
    static void CreateInstance()   ///只需要执行一次的部分
    {
        m_instance = new MyCAS();
        static CGarhuishou cl;
    }
    
    static MyCAS *GetInstance()   ///得到对象的接口函数
    {
        call_once(g_flag,CreateInstance);   ///第一个参数是个标记,第二个参数是只要执行的函数
        return m_instance;
    }
    /*
    ...
    */
};

以上是关于单例设计模式和多线程的主要内容,如果未能解决你的问题,请参考以下文章

你所不知道的单例模式和多线程并发在单例模式中的影响

Java线程和多线程——单例类中的线程安全

spring使用单例 线程怎么解决并发

单例和多线程

线程学习--单例和多线程ThreadLocal

架构师养成记--6.单例和多线程ThreadLocal