多线程环境中的单例模式

1. 单例模式是什么

单例模式保证某一个类在系统中只存在一个实例对象。无论任何时候有且只有一个实例对象。

单例模式应用场景:
在我们经常会碰到只需要创建一个实例的情况,例如: 配置文件,日志对象,线程池,缓存等。
比如,设置一个实例对象专门负责配置文件的读写,可以避免多个实例对象出现同时读写配置的文件的情况(造成日志错乱)
线程池,线程池对象需要占用大量资源,如果多次实例化线程池对象会造成很大的而资源浪费。

2.编写单例模式基本步骤

  1. 将构造函数声明为私有
  2. 在类中声明一个私有的静态类对象
  3. 定义一个静态public类型对象获取函数

单例模式又分为“饿汉”和“懒汉”模式。
饿汉模式:类对象立即加载,在类加载初始化的时候就主动创建实例;
懒汉模式 :等到真正使用的时候才去创建实例,不用时不去主动创建。

特点与选择:
由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。
在访问量较小时,采用懒汉实现。这是以时间换空间。

3. “饿汉”模式

“饿汉”模式,无论是否调用该类的实例,进程都会创建一个该类的实例。饿汉模式是线程安全的,因为在程序编译阶段,程序就创建好了实例,不会有多个线程同时去创建实例。

#include<iostream>
using namespace std;

class Singleton{
    private:
        static Singleton *single;
        Singleton(){}
        
    public:
        static Singleton* getIntance();
        
};
Singleton *Singleton::single = new Singleton;
Singleton *Singleton::getIntance()
{
    cout<<"getIntance\n";
    return single;
}   

4. “懒汉”模式

懒汉模式不同于饿汉模式,它没有提前(编译阶段)创建实例对象,而是在需要使用时才创建实例对象,这样就带来了线程安全性问题(有可能多个线程同时创建实例对象)
单线程下的懒汉模式

#include<iostream>

using namespace std;

class Singleton{
    private:
        static Singleton *single;
        Singleton(){}
        
    public:
        static Singleton* getIntance();
        
};
Singleton *Singleton::single = NULL;
Singleton *Singleton::getIntance()
{
    if(single == NULL)
    {
        single = new Singleton;
    }
    return single;
}   

多线程环境下懒汉模式

class Singleton{
    private:
        static pthread_once_t g_once_control;
        static pthread_mutex_t mutex;
        static const Singleton *single;
        Singleton(){}
        ~Singleton(){
            pthread_mutex_destory(&mutex);
        }

        static void initMutex(){
            pthread_mutex_init(&mutex,NULL);
        }
        
    public:
        static Singleton* getIntance();
        
};

Singleton::single = NULL;
pthread_once_t Singleton::g_once_control = PTHREAD_ONCE_INIT;

Singleton *Singleton::getIntance()
{
    pthread_once(&g_once_control,initMutex());
    pthread_mutex_lock(&mutex);
    if(single == NULL)
    {
        single = new Singleton;
    }
    pthread_mutex_unlock(&mutex);
    return single;
}   
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 单例模式(SingletonPattern)一般被认为是最简单、最易理解的设计模式,也因为它的简洁易懂,是项目中最...
    成热了阅读 9,787评论 4 34
  • 【学习难度:★☆☆☆☆,使用频率:★★★★☆】直接出处:单例模式梳理和学习:https://github.com/...
    BruceOuyang阅读 3,919评论 1 2
  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 9,873评论 1 14
  • 1 单例模式的动机 对于一个软件系统的某些类而言,我们无须创建多个实例。举个大家都熟知的例子——Windows任务...
    justCode_阅读 5,310评论 2 9
  • 文\落雪 都说喝酒脸不红的人 不易醉 却不知脸不红 心已碎 是酒精在作祟 听不了 酒桌上 流水账似的回味 ...
    落雪有晴空阅读 2,732评论 10 7