- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
本文由简悦SimpRead转码,原文地址
本我们主要讲解单例模式的双重检查锁模式为什么必须加volatile?
什么是单例模式
单例模式指的是,保证一个类只有一个实例,并且一个可以全局的。
为什么需要使用单例模式
那么我们为什么需要单例呢?其中**一个理由,那就是为了节省内存、节省计算。**因为在很多情况
下,我们只需要一个实例就够了,如果出现的实例,反而纯属浪费。
下面我们举一个例子来说明这个情况,以一个初始化比较耗时的类来说,代码如下所示:
publicExpensiveResource(){
这个类在构造的时候,需要查询数据库并对查到的数据做大量计算,所以在第一次构造时,我们花了很
多时间来初始化这个对象。但是假设数据库里的数据是不变的,我们就可以把这个对象保存在内存中,
那么以后开发的时候就可以直接用这同一个实例了,不需要再次构建新实例。如果每次都重成新的
实例,则会造成的浪费,实在没有必要。
接下来看看需要单例的第二个理由,那就是为了保证结果的正确。**比如我们需要一个全局的计数
器,用来统计人数,如果有多个实例,反而会造成。
另外呢,就是为了方便管理。**很多工具类,我们只需要一个实例,那么我们通过统一的,比如
通过getInstance方法去获取这个单例是很方便的,太多实例不但没有帮助,反而会让人眼花缭乱。
一般单例模式的类结构如下图所示:有一个私有的Singleton类型的singleton对象;同时构造方法也
是私有的,为了防止他人调用构造函数来生成实例;另外还会有一个public的getInstance方法,可通
过这个方法获取到单例。
双重检查锁模式的写法
单例模式有多种写法,我们重点介绍一下和volatile强相关的双重检查锁模式的写法,代码如下所示:
synchronized(Singleton.class){
在这里我将重点讲解getInstance方法,方法中首先进行了一次if(singletonnull)的检查,然后是
synchronized同步块,然后又是一次if(singletonnull)的检查,最后是singleton=new
Singleton()来生成实例。
我们进行了两次if(singletonnull)检查,这就是“双重检查锁”这个名字的由来。这种写法是可以保
证线程安全的,假设有两个线程同时到达synchronized语句块,那么实例化代码只会由其中先抢到锁
的线程执行一次,而后抢到锁的线程会在第二个if判断中发现singleton不为null,所以跳过创建实例
的语句。再后面的其他线程再来调用getInstance方法时,只需判断第一次的if(singletonnull),
然后会跳过整个if块,直接return实例化后的对象。
这种写法的优点是不仅线程安全,而且延迟加载、效率也更高。
讲到这里就涉及到了一个常见的问题,面试官可能会问你,“为什么要double-check?去掉任何一次
的check行不行?”
我们先来看第二次的check,这时你需要考虑这样一种情况,有两个线程同时调用getInstance方法,
由于singleton是空的,因此两个线程都可以通过第一重的if判断;然后由于锁机制的存在,会有一个
线程先进入同步语句,并进入第二重if判断,而另外的一个线程就会在外面等待。
不过,当第一个线程执行完newSingleton()语句后,就会synchronized保护的区域,这时如果
没有第二重if(singletonnull)判断的话,那么第二个线程也会创建一个实例,此时就破坏了单例,这
肯定是不行的。
而对于第一个check而言,如果去掉它,那么所有线程都会串行执行,效率低下,所以两个check都
是需要保留的。
在双重检查锁模式中为什么需要使用volatile关键字
相信细心的你可能看到了,我们在双重检查锁模式中,给singleton这个对象加了volatile关键字,那
**为什么要用volatile呢?**主要就在于singleton=newSingleton(
您可能关注的文档
最近下载
- 《手术室工作》课件.pptx VIP
- 老年社区获得性肺炎.ppt VIP
- 自控专业工程设计用典型条件表.xls VIP
- 书院大桥工程环境影响报告书的公告环评报告.pdf VIP
- 太仓协鑫煤炭码头工程固体废物污染防治设施竣工环境保护.PDF VIP
- 9.2奉献社会我践行课件(共43张PPT)-2025-2026学年统编版道德与法治八年级上册.pptx VIP
- GB_T50644-2011:油气管道工程建设项目设计文件编制标准.pdf VIP
- 工业视觉系统运维员必备知识考试题库(浓缩400题).docx VIP
- 《手术室工作》课件.pptx VIP
- 2022输变电典型运维项目费用参考标准.docx VIP
原创力文档


文档评论(0)