C++设计模式:单例模式

什么是单例模式?
单例模式指在整个系统生命周期里,保证一个类只能产生一个实例,确保该类的唯一性。

单例模式分类有哪些?
单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同:
懒汉式:指系统运行中,实例并不存在,只有当需要使用该实例时,才会去创建并使用实例。(这种方式要考虑线程安全)
饿汉式:指系统一运行,就初始化创建实例,当需要时,直接调用即可。(本身就线程安全,没有多线程的问题)

懒汉实现:

class Single
{
    private:
       Single() {}
       static Single *p;

    public:
       static Single *getInstance();
};

Single *Single::p = NULL;

Single *Single::getInstance()
{
    if (p == NULL)
    {
        p = new Single();
    }
    return p;
}

饿汉实现:

class Single
{
    private:
       Single() {}
       static Single *p;

    public:
       static Single *getInstance();
};

Single *Single::p = new Single();

Single *Single::getInstance()
{
    return p;
}

多线程双重锁定的单例模式:
(1) 当两个或两个以上的线程同时执行GetInstance的时候,肯定有一个线程拿到锁并把单例对象创建好了,故这个首线程退出后,其它的线程再进入也无法再创建新的对象了
(2) 存在的问题是首线程之外的线程明明没有了创建对象的权利还天天的去拿锁,造成资源的浪费。
为解决上述问题引入双重锁定,如下:
所谓的双重锁定只不过是在上锁之前也进行一下检查,如果说你连拿到锁的资格都没有你凭啥去创建对象。

#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <thread>
#include <mutex>
#include <cstdlib>
using namespace std;

mutex mtx;
#define NUM 5
class Single
{
    public:
        static Single *getInstance();
         
        void Print()
        {
            if(m_Single == NULL)
            {
                printf("m_Single is NULL!\n");
            }
            cout<<this<<" 刘亦菲 是一个美人!"<<endl;
        }
        Single()
        {
            printf("Single()\n");
        }
        ~Single()
        {
            printf("~Single()\n");
        }
        
    private: 
        Single(const Single &signal);
        Single &operator=(const Single &signal);
        
        static Single *m_Single;
        
};

Single *Single::m_Single = NULL;
Single* Single::getInstance()
{
    if (m_Single == NULL)
    {
        mtx.lock();
        if (m_Single == NULL)
        {
            m_Single = new Single;
            mtx.unlock();
            return m_Single;
        }
    }
    mtx.unlock();
    return m_Single;
}
void threadFun()
{
    printf("我的线程开始执行了!\n");
    Single *sig = Single::getInstance();
    sig->Print();
    printf("我的线程结束了!\n");
}
int main()
{
    thread thd1,thd2;
    thd1 = thread(threadFun);
    thd2 = thread(threadFun);
    thd1.join();
    thd2.join();
    return 0;
}

 

posted @ 2023-06-05 17:03  韓さん  阅读(15)  评论(0编辑  收藏  举报