单例模式---线程安全实现

文章目录

1.单例模式的特点😊

1.全局只有一个类的static实例存在;

2.不允许直接实例化,构造函数为私有的,只通过一个类的静态方法获取该实例;

2.单例模式两种实现🤣🤗😊

2.1 饿汉式

饿汉式是在类加载的时候就会创造实例,会造成资源的浪费。 具体:内部先定义并初始化好了一个静态实例。获取方法中直接返回实例。

特点:线程安全,会造成资源浪费

实现:

cpp 复制代码
class Singleton {
private:
    static Singleton instance;

    // 私有构造函数,防止类外实例化对象
    Singleton() {}

public:
    // 获取实例的静态方法
    static Singleton& getInstance() {
        return instance;
    }

    // 其他成员函数
    void doSomething() {
        // do something
    }
};

// 静态成员变量需要在类外初始化
Singleton Singleton::instance;

int main() {
    // 获取单例对象实例
    Singleton& singleton = Singleton::getInstance();
    // 调用单例对象的方法
    singleton.doSomething();

    return 0;
}

2.2 懒汉式

懒汉式是在需要时才创建实例,通过获取实例方法获取实例。

具体:内部定义一个静态实例,获取方法中判断实例是否为空,空则初始化实例;否则返回该实例

特点:避免资源浪费,造成线程安全问题。

实现

cpp 复制代码
class Singleton {
private:
    // 静态成员变量,用于保存单例实例
    static Singleton* instance;
    
    // 构造函数私有化,防止外部创建实例
    Singleton() {}
    
public:
    // 静态成员函数,用于获取单例实例
    static Singleton* getInstance() {
        // 判断实例是否为空,如果为空则创建实例
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
    
    // 删除拷贝构造函数和拷贝赋值运算符,防止被复制
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

Singleton* Singleton::instance = nullptr;  // 初始化静态成员变量

int main() {
    // 获取单例实例
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();
    
    // 判断两个实例是否相同
    if (singleton1 == singleton2) {
        cout << "两个实例相同" << endl;
    } else {
        cout << "两个实例不相同" << endl;
    }
    
    return 0;
}

3.传统单例模式的线程安全问题

饿汉式是线程安全的,懒汉式不是

当多线程执行getInstance时候,如果线程A判断当前实例为空,线程B正好判断到也为空,就会申请资源;当线程A恢复了后,继续执行,也会申请内存空间;就会出现两个实例,这就会出现问题;

4.解决方法

4.1静态局部变量

cpp 复制代码
class Singleton {
private:
    Singleton() {}
    
public:
    static Singleton* getInstance() {
        static Singleton instance;
        return &instance;
    }
};

4.2加锁

cpp 复制代码
class Singleton {
private:
    // 静态成员变量,用于保存单例实例
    static Singleton* instance;
    
    // 构造函数私有化,防止外部创建实例
    Singleton() {}
    
public:
    // 静态成员函数,用于获取单例实例
    static Singleton* getInstance() {
        // 判断实例是否为空,如果为空则创建实例
        Mutexlock lock(mutex);//加锁
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
    
    // 删除拷贝构造函数和拷贝赋值运算符,防止被复制
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

Singleton* Singleton::instance = nullptr;  // 初始化静态成员变量

int main() {
    // 获取单例实例
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();
    
    // 判断两个实例是否相同
    if (singleton1 == singleton2) {
        cout << "两个实例相同" << endl;
    } else {
        cout << "两个实例不相同" << endl;
    }
    
    return 0;
}

4.3双重检查锁(DCL)

cpp 复制代码
class Singleton {
private:
    // 静态成员变量,用于保存单例实例
    static Singleton* instance;
    
    // 构造函数私有化,防止外部创建实例
    Singleton() {}
    
public:
    // 静态成员函数,用于获取单例实例
    static Singleton* getInstance() {
        // 判断实例是否为空,如果为空则创建实例
        if (instance == nullptr) {
        Mutexlock lock(mutex);
        if(instance==nullptr)
            instance = new Singleton();
        }
        return instance;
    }
    
    // 删除拷贝构造函数和拷贝赋值运算符,防止被复制
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

Singleton* Singleton::instance = nullptr;  // 初始化静态成员变量

int main() {
    // 获取单例实例
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();
    
    // 判断两个实例是否相同
    if (singleton1 == singleton2) {
        cout << "两个实例相同" << endl;
    } else {
        cout << "两个实例不相同" << endl;
    }
    
    return 0;
}

4.4pthread_once

cpp 复制代码
#include<iostream>
class singleton{
public:
static singleton& getinstance()
{
pthread_once(&ponce,init);//保证该函数只被执行一次
return instance;
}
private:
static void init()
{
instance=new singleton();
}
singleton(){}
~singleton(){}
static pthread_once_t  ponce;
static singleton* instance;
};
singleton::ponce=PTHREAD_ONCE_INIT;
singleton::instance=nullptr;
相关推荐
不想写代码的星星18 小时前
std::function 详解:用法、原理与现代 C++ 最佳实践
c++
樱木Plus3 天前
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)
c++
willow3 天前
Axios由浅入深
设计模式·axios
RuoZoe4 天前
重塑WPF辉煌?基于DirectX 12的现代.NET UI框架Jalium
c语言
blasit5 天前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip
七月丶5 天前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞5 天前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼5 天前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟5 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式