多线程---单例模式


单例模式

单例模式:是非常典型常用的一种设计模式
一份资源只能被申请加载一次/单例模式的方法创建的类在当前进程中只有一个实例

实现单例模式

饿汉方式

资源的程序初始化的时候就去加载,后面使用的时候直接使用,使用的时候比较流畅,有可能会加载用不上的资源,导致程序初始化时间比较慢。

#include <cstdio>

class single_instance
{
    public:
        int * get_instance(){
            return &_data;
        }
    private:
        static int _data;
};
int single_instance::_data = 10;//静态成员变量需要在类外初始化
int main()
{
    single_instance a1;
    single_instance b1;

    printf("a1:%d-%p\n", *(a1.get_instance()), a1.get_instance()); 
    printf("b1:%d-%p\n", *(b1.get_instance()), b1.get_instance()); 
}

在这里插入图片描述

懒汉模式

资源在使用的时候发现还没加载,则申请加载
初始化比较快,第一次运行某个模块的时候比较慢,因为需要加载资源

#include <cstdio>
#include <thread>
#include <mutex>
std::mutex g_mutex;
class single_instance
{
    public:
        volatile int *get_instance() {
            //不管——data资源是否已经被加载,每次都要加锁判断,然后解锁
            //若资源已经加载过了,加锁解锁就有点浪费资源,并且容易造成锁冲突
            //4. 二次判断,避免每次都会加锁解锁
            if (_data == NULL) {
                //-----------------//
                g_mutex.lock();//3. 实现线程安全
                if (_data == NULL) {
                    _data = new int;
                    *_data = 10;
                }
                g_mutex.unlock();
            }
            return _data;
        }
    private:
        //1. static 保证所有对象使用同一份资源
        //2. volatile 防止编译器过度优化
        volatile static int *_data;
};
volatile int *single_instance::_data = NULL;

int main()
{
    single_instance a1;
    single_instance b1;

    printf("a1:%d-%p\n", *(a1.get_instance()), a1.get_instance()); 
    printf("b1:%d-%p\n", *(b1.get_instance()), b1.get_instance()); 
}

在这里插入图片描述

注意事项:

  • 使用static保证所有对象使用同一份资源
  • 使用volatile,防止编译器过度优化
  • 实现线程安全,保证资源判断以及申请过程是安全的
  • 外部二次判断,以及避免资源已经加载成功每次获取都需要加锁解锁,以及带来的锁冲突
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值