单例模式,懒汉饿汉,线程安全,double checked locking的问题

本文主要是介绍单例模式,懒汉饿汉,线程安全,double checked locking的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概览

  • 本文目的
  • 单例
    • 饿汉模式
    • 懒汉模式
  • 线程安全的Singleton实现
    • 懒汉普通加锁
    • double checked locking
      • double checked locking 靠不住?
      • 静态局部变量实现
  • 尾语


本文目的

  之前在看《Linux多线程服务端编程-使用muduo C++网络库》,看到 2.5 线程安全的Singleton实现 时,里面对单例模式的线程安全有这么一句话, 人们一直认为double checked locking是王道,有“神牛”指出由于乱序执行的影响,DCL(double checked locking)是靠不住的。 这对于没有经验的初学者有些难懂,所以我打算在这篇文章里,讲一讲,什么是单例,什么是double checked locking,double checked locking又为什么靠不住。


单例

 
  单例模式,简单来说就是保证一个类最多存在一个实例,并且这种保证是来自于设计者,而不是使用者。而实现这样需求的办法就是:让类的构造函数私有,在类内创建一个静态对象,并创建一个公有的静态方法访问这个对象。
  可能会有人问, 为什么创建的对象必须是静态的? 因为我们在外面没办法创建这个对象,需要通过类来调用方法,而不是通过对象调用方法。要想通过类来调用方法,那么这个方法必须是static静态的(不需要this指针)。而静态的方法内只能调用类中的静态数据,所以,类内创建的对象必须是静态的。(下面可以看具体的代码)
  单例模式的实现有懒汉模式和饿汉模式。下面是这两种模式的实现。


饿汉模式

 
  饿汉模式,就是在类定义的时候就实例化了(因为饿,主观能动性强 - . -)。
  是线程安全的,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现(不用锁机制,开销小),可以实现更好的性能。

 5 class Singleton{6     private:7         Singleton(){8         cout<<"i am single"<<endl;9         }10 11         static Singleton* instance;12     public:13         static Singleton* getInstance(){14             return instance;15         }16 };17 18 Singleton* Singleton:: instance = new Singleton();19 20 int main(){21 	Singleton* one = Singleton::getInstance();22 	Singleton* two = Singleton::getInstance();23 	if(one == two){24 		cout<<"确实是单例!"<<endl;

这篇关于单例模式,懒汉饿汉,线程安全,double checked locking的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/449401

相关文章

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

解决JSONField、JsonProperty不生效的问题

《解决JSONField、JsonProperty不生效的问题》:本文主要介绍解决JSONField、JsonProperty不生效的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录jsONField、JsonProperty不生效javascript问题排查总结JSONField

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地