线程安全的单例模式:饿汉模式&懒汉模式

简介: 线程安全的单例模式:饿汉模式&懒汉模式

一、单例模式


单例模式:一种典型的设计模式。


应用场景:


       一个类只能实例化一个对象,向外提供统一访问接口的场景。


作用:


       对资源进行统一管理,以及避免数据在不同对象中出现不同的体现。


两种实现:饿汉模式&懒汉模式


二、饿汉模式


1.特点


       资源静态化。


       在程序初始化阶段,完成对象的实例化。


       以空间换时间的思想,在使用的时候就可以直接使用。


优点:


       在构造对象时,不需要考虑线程安全问题。


缺点:


       初始化速度慢。


2.实现关键


1)如何在程序初始化阶段完成对象的实例化


       解决方法:在类中定义唯一的对象,且用static修饰对象


2)如何让一个类只能有一个对象


       解决方法:私有化构造函数


3.代码实现


#include<iostream>
class Singleton {
  private:
    int _data;
    static Singleton _eton;
    Singleton () : _data(0) {}
  public:
    static Singleton *GetInstance() {
      return &_eton;
    }
    int *GetData() {
      return &_data;
    }
};
Singleton Singleton::_eton;
int main() {
  std::cout << Singleton::GetInstance() -> GetData() << std::endl;
  return 0;
}


三、懒汉模式


1.特点


       对象在访问使用的时候才去实例化。


       一种延迟加载的思想,用的时候再去加载,节省资源。


优点:


       初始化速度快。


缺点:


       在构造对象时,需要考虑线程安全问题。


2.实现关键


1)如何在访问使用的时候采取实例化对象


       解决方法:在类中定义唯一的对象指针,且用static修饰


2)如何让一个类只能有一个对象


       解决方法:私有化构造函数


总结:


       1.定义静态对象指针;


       2.构造函数私有化;


       3.加锁保护对象构造过程;


       4.double check提高效率;


       5.volatile关键字修饰,防止编译器过度优化。


3.代码实现


#include<iostream>
#include<mutex>
class Singleton {
  private:
    int _data;
/*volatile*/static Singleton *_eton;//c语言实现时,需要加上volatile关键字,保持_eton内存可见性,防止编译器过度优化
    static std::mutex _mutex;
    Singleton() {}
  public:
    static Singleton *GetInstance(){
      if (_eton == NULL) {//双层检测,降低锁冲突概率
        _mutex.lock();//加锁,确保线程安全
        if (_eton == NULL) {
          _eton = new Singleton();
        }
        _mutex.unlock();
      }
      return _eton;
    }
    int *GetData() {
      return &_data;
    }
};
Singleton* Singleton::_eton = NULL;
std::mutex Singleton::_mutex;
int main() {
  std::cout << Singleton::GetInstance() -> GetData() << std::endl;
  return 0;
}
目录
打赏
0
0
0
0
6
分享
相关文章
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
90 0
|
5月前
|
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
103 17
|
5月前
|
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
99 26
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程
|
7月前
|
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
538 2
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
7月前
|
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
109 3
多线程编程核心:上下文切换深度解析
在多线程编程中,上下文切换是一个至关重要的概念,它直接影响到程序的性能和响应速度。本文将深入探讨上下文切换的含义、原因、影响以及如何优化,帮助你在工作和学习中更好地理解和应用多线程技术。
132 4
|
7月前
|
多线程编程核心:上下文切换深度解析
在现代计算机系统中,多线程编程已成为提高程序性能和响应速度的关键技术。然而,多线程编程中一个不可避免的概念就是上下文切换(Context Switching)。本文将深入探讨上下文切换的概念、原因、影响以及优化策略,帮助你在工作和学习中深入理解这一技术干货。
144 10
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等