• 单例模式的介绍


    单例模式(Singleton)是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。其核心思想是通过限制类的实例化次数,防止多个实例同时存在,从而避免了多线程竞争和资源浪费,提高了代码的可维护性和可扩展性。

    单例模式通常适用于以下场景:

    1. 系统中某个类只能存在一个实例,例如系统配置、日志管理器等。
    2. 需要频繁访问同一个对象或资源,但又不希望每次都去创建新的对象。
    3. 为了确保数据的一致性和完整性,需要限制全局变量的访问权限。

    实现单例模式的方法有很多种,常见的包括懒汉式、饿汉式、双重检查锁等。具体实现方式可以根据实际情况选择,但需要注意线程安全性、效率等问题。

    在 C++ 中,可以使用静态成员变量或者静态局部变量来实现单例模式。静态成员变量在程序启动时就会被初始化,因此是线程安全的,但需要手动释放资源。静态局部变量则是在首次调用时初始化,虽然不需要手动释放资源,但需要考虑线程安全性和可重入性等问题。

    总之,单例模式是一种简单而又实用的设计模式,可以在很多场景下提高代码的可维护性和可扩展性。在使用单例模式时,需要根据具体情况选择适合的实现方式,并考虑线程安全性、效率等问题。

    在单线程中,这两种方式都可以使用。然而,在多线程环境下,懒汉式单例模式可能会引发线程安全问题,因为多个线程可能同时访问并创建该单例对象。为了解决这个问题,可以使用以下两种方式:

    1. 加锁:在getInstance函数中使用互斥锁来保证线程安全。

    2. 双检查锁:在getInstance函数中使用双检查锁机制,先检查instance是否为空,如果为空,则获取互斥锁,再次检查instance是否为空,如果为空,则创建对象。

    综上所述,饥汉式单例模式更适合在线程中使用,因为它没有线程安全问题,并且更高效,因为它在程序启动时就已经创建了实例。但是需要注意的是,饥汉式单例模式可能会增加程序启动时间和内存使用。如果单例对象非常庞大,或者不一定在每次都被使用时都需要创建,那么懒汉式单例模式可能更适合使用。

    1. #include
    2. #include
    3. #include
    4. class Singleton {
    5. private:
    6. static Singleton* instance;
    7. static std::mutex mutex;
    8. Singleton() {}
    9. public:
    10. static Singleton* getInstance() {
    11. std::lock_guard lock(mutex);
    12. if (instance == nullptr) {
    13. instance = new Singleton();
    14. }
    15. return instance;
    16. }
    17. void showMessage() {
    18. std::cout << "Hello from Singleton!" << std::endl;
    19. }
    20. };
    21. Singleton* Singleton::instance = nullptr;
    22. std::mutex Singleton::mutex;
    23. void threadFunction() {
    24. Singleton* singleton = Singleton::getInstance();
    25. singleton->showMessage();
    26. }
    27. int main() {
    28. const int numThreads = 5;
    29. std::thread threads[numThreads];
    30. for (int i = 0; i < numThreads; ++i) {
    31. threads[i] = std::thread(threadFunction);
    32. }
    33. for (int i = 0; i < numThreads; ++i) {
    34. threads[i].join();
    35. }
    36. return 0;
    37. }

    当在多线程环境中使用单例模式时,需要考虑线程安全性以避免多个线程同时创建实例或访问共享资源的问题。以下是一个示例,在多线程环境下使用懒汉式单例模式,并通过加锁确保线程安全:。。。。

    在上面的示例中,我们使用了 std::mutex 来确保在 getInstance() 函数中对单例对象进行加锁操作,从而保证多线程环境下的线程安全性。每个线程调用 getInstance() 函数来获取单例实例,并调用 showMessage() 方法输出信息。

    这样,在多线程环境下,每个线程都会获得同一个实例,并且不会出现多个实例被创建的情况。通过加锁操作,确保了线程安全性。

    1. #include
    2. class Singleton {
    3. public:
    4. static Singleton& getInstance() {
    5. static Singleton instance; // 在首次调用时初始化静态局部变量
    6. return instance;
    7. }
    8. void showMessage() {
    9. std::cout << "Hello, I am a singleton instance!" << std::endl;
    10. }
    11. private:
    12. Singleton() {} // 将构造函数私有化,防止外部实例化对象
    13. Singleton(const Singleton&) = delete; // 禁用拷贝构造函数
    14. Singleton& operator=(const Singleton&) = delete; // 禁用赋值运算符
    15. };
    16. int main() {
    17. Singleton& singleton = Singleton::getInstance();
    18. singleton.showMessage();
    19. // 以下代码会报错,因为构造函数是私有的
    20. // Singleton newSingleton;
    21. // Singleton anotherSingleton = singleton;
    22. return 0;
    23. }
    1. class Singleton {
    2. private:
    3. static Singleton* instance;
    4. Singleton(){}
    5. public:
    6. static Singleton* getInstance(){
    7. if(instance == nullptr){
    8. instance = new Singleton();
    9. }
    10. return instance;
    11. }
    12. };
    13. Singleton* Singleton::instance = nullptr;

  • 相关阅读:
    Elasticsearch:Open Crawler 发布技术预览版
    Linux下的一些基础功能
    MATLAB神经网络编程(一)——感知器
    uni-app的uni-list在真机调试中无法显示
    qt设计界面的属性编辑器不见了,如何恢复显示
    全志V853的NPU的demo试玩
    16-JavaSE基础巩固项目:拼图小游戏
    [环境搭建]OpenHarmony开发环境搭建
    Java项目:在线美食分享推荐系统(java+SSM+JSP+jQuery+Mysql)
    常用消息中间件
  • 原文地址:https://blog.csdn.net/laocooon/article/details/136221917