糟糕的双重检查加锁(DCL)
在Java并发编程时,同步都会存在着巨大的性能开销,因此,人们使用了很多的技巧来降低同步的影响,这其中有一些技巧很好,但是也有一些技巧存在一些缺陷,下面要结束的双重检查加锁(DCL)就是有缺陷的一类。
由于早期的JVM在性能上存在一些有待优化的地方,因此在并发编程中,延迟初始化经常被用来降低程序的开销。编写正确的延迟初始化需要使用同步,但是直接在初始化之前使用同步会对性能产生影响。所以一些人就提出了双重检查加锁,并声称能够解决这个矛盾。如图所示就是双重检查加锁的代码。
上图代码中,对Resource资源进行延时初始化,在初始化之前需要判断资源是否已经初始化过,所以进行了第一次没有同步的非空判断,resource对象却是为空时,再来对resource对象进行初始化,并将这部分初始化的代码加了类锁进行同步。这代码咋一看确实非常好,首先在第一次非空判断的时候,没有进行同步,只要对象完成了初始化,那么代码就永远走不到同步块中,所以不会有性能问题。但是仔细分析之后,其实是有缺陷的。
这段代码的缺陷就是线程有可能会使用一个仅被部分构造的Resource对象。双重检查加锁的问题在于,当在没有同步的情况下读取一个共享对象的时候,最坏的情况下,有可能得到的是一个失效的值。这是由于我们在判断对象是否完成初始化是,只是判断对象的引用是否非空,然后在初始化对象时,JVM会在堆上给对象分配一块内存,然后JVM会干两件事,将内存的地址作为引用分配给变量和在堆上初始化这个对象,但是这两件事的先后顺序是不确定的,因此有可能resource非空,但是对象并没有初始化完成。
所以在实际编程中一定要注意尽量不要使用双重检查加锁,如果一定要使用,那么可以将resource声明为volatile类型,这种方式对性能的影响是很小的,并且还能保证每个线程都能获取到最新的对象。
糟糕的双重检查加锁(DCL)的更多相关文章
- 单例---被废弃的DCL双重检查加锁
被废弃的单例的DCL双重检查加锁/* *单例模式 *单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点. *加同步锁的单例模式,适合在多线程中使用. */ class Singleton{ ...
- 【线程安全】—— 单例类双重检查加锁(double-checked locking)
1. 三个版本单例类的实现 版本1:经典版 public class Singleton { public static Singleton getInstance() { if (instance ...
- 双重检查加锁机制(并发insert情况下数据重复插入问题的解决方案)
双重检查加锁机制(并发insert情况下数据重复插入问题的解决方案) c#中单例模式和双重检查锁 转:https://blog.csdn.net/zhongliangtang/article/deta ...
- 单例模式的两种实现方式对比:DCL (double check idiom)双重检查 和 lazy initialization holder class(静态内部类)
首先这两种方式都是延迟初始化机制,就是当要用到的时候再去初始化. 但是Effective Java书中说过:除非绝对必要,否则就不要这么做. 1. DCL (double checked lockin ...
- DCL,即Double Check Lock,中卫双重检查锁定。
DCL,即Double Check Lock,中卫双重检查锁定. [Java并发编程]之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码) 关于单例.关于DCL: ...
- Java并发(七):双重检验锁定DCL
双重检查锁定(Double Check Lock,DCL) 1.懒汉式单例模式,无法保证线程安全: public class Singleton { private static Singleton ...
- 双重检查锁定与延迟初始化(转自infoq)
很好的文章,转自http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization 在java程序中,有 ...
- Java中的双重检查锁(double checked locking)
最初的代码 在最近的项目中,写出了这样的一段代码 private static SomeClass instance; public SomeClass getInstance() { if (nul ...
- volatile双重检查锁定与延迟初始化
一.基本概念: 1.volatile是轻量级的synchronized,在多核处理器开发中保证了共享变量的“可见性”.可见性的意思是,当一个线程修改一个共享变量时,另一个线程能读到这个修改的值. 2. ...
随机推荐
- 通过CSS禁止Chrome自动为输入框添加橘黄色边框,修改/禁止 chrome input边框颜色,
1 /*Chrome浏览器 点击input 黄色边框 禁用*/ .NoOutLine:focus{outline: none} <asp:TextBox ID="txtTeleph ...
- 笨笨-歌词伴侣V1.2(酷狗KRC转LRC,LRC歌词批量下载)
最近由于某些热心博友在我CSDN博客上使用了我的软件,提出了一些建议,看到自己的成果有人使用并且提出了一些建议,焉有不高兴之理!刚好碰上最近研究UI界面,有了一个初步的框架,就顺手将歌词相关功能集 ...
- 转载RabbitMQ入门(3)--发布和订阅
发布和订阅 (使用java 客户端) 在先前的指南中,我们创建了一个工作队列.这工作队列后面的假想是每一个任务都被准确的传递给工作者.在这部分我们将会做一些完全不同的事情–我们将一个消息传递给多个消费 ...
- 【转】./a.out 2>&1 > outfile
原文网址:http://www.cnblogs.com/zhaoyl/archive/2012/10/22/2733418.html APUE 3.5关于重定向有个容易迷惑人的问题: ./a.out ...
- 关于UT的一些总结
本文是个人对于UT的一些想法和总结,参考时建议请查阅官方资料. 转载请注明出处:http://www.cnblogs.com/sizzle/p/4476392.html 测试思想 编写UT测试代码,通 ...
- HDU 5874 Friends and Enemies
Friends and Enemies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- bug报告-常用词汇中英对照表
- Multiple View Geometry in Computer Vision Second Edition by Richard Hartley 读书笔记(二)
// Chapter 2介绍的是2d下的投影变换,摘录下了以下定理 Result 2.1. The point x lies on the line l if and only if xTl = 0. ...
- linux常用命令之--磁盘管理命令
linux的磁盘管理命令 1.查看磁盘空间 df:用于显示磁盘空间的使用情况 其命令格式如下: df [-option] 常用参数: -i:使用inodes显示结果 -k:使用KBytes显示结果 - ...
- NIS Edit&Nsis打包程序发布(安装和卸载)
转自:http://blog.csdn.net/signjing/article/details/7855855 注意:首选得明确自己需要打包的程序,以及程序需要的dll文件,资源文件等. 1.下载N ...