单例模式双重检查锁与Volatile关键字作用.pdfVIP

单例模式双重检查锁与Volatile关键字作用.pdf

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 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(

文档评论(0)

zhishifuwu + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档