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

文章目录

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;
相关推荐
笨手笨脚の3 分钟前
设计模式-状态模式
设计模式·状态模式·行为型设计模式
破晓之翼2 小时前
控制论的定义、工程意义及系统功能整合
设计模式·软件工程·产品经理·学习方法
tt5555555555552 小时前
CSDN 教程:C++ 经典字符串与栈算法题逐行详解
c++·算法·哈希算法
周杰伦fans2 小时前
C++ 中的 `::` 全局作用域符
开发语言·c++
bkspiderx3 小时前
C++设计模式之行为型模式:状态模式(State)
c++·设计模式·状态模式
会开花的二叉树3 小时前
分布式文件存储 RPC 服务实现
c++·分布式·网络协议·rpc
老侯(Old monkey)3 小时前
C语言:冒泡法排序
c语言·函数调用·指针·冒泡法排序
abcd_zjq3 小时前
VS2026+QT6.9+opencv图像增强(多帧平均降噪)(CLAHE对比度增强)(边缘增强)(图像超分辨率)
c++·图像处理·qt·opencv·visual studio
Algebraaaaa4 小时前
Qt中的字符串宏 | 编译期检查和运行期检查 | Qt信号与槽connect写法
开发语言·c++·qt
迎風吹頭髮8 小时前
UNIX下C语言编程与实践58-UNIX TCP 连接处理:accept 函数与新套接字创建
c语言·网络·unix