博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DCL实现单例要不要加volatile修饰
阅读量:2065 次
发布时间:2019-04-29

本文共 1074 字,大约阅读时间需要 3 分钟。

单例模式的DCL(Double-checked locking 双重校验锁定模式)写法:

public class DclSingleton {    private static volatile DclSingleton dclSingleton = null;    public static DclSingleton getDclSingleton(){        if(dclSingleton == null){            synchronized (DclSingleton.class){                if(dclSingleton == null){                    dclSingleton = new DclSingleton();                }            }        }        return dclSingleton;    }}

可以看到加了两个dclSingleton == null的判断,主要是为了提高效率,如果最外面的dclSingleton == null不要的话,每次获取对象的时候都需要进行加锁操作,比较耗时间,因为只需要第一个获取锁的创建完对象,后面就不需要在进加锁的方法里了,大大提高效率。

但是有个问题,我们的声明dclSingleton要不要加volatile修饰呢?答案是肯定需要要明白为什么,首选需要明白对象的创建过程。

public class ObjTest {    public static void main(String[] args) {        Object object = new Object();    }}

运行这个类,然后使用javap -c  ObjTest.class 命令查看生成的字节码指令。

可以看到对象的创建并非原子操作,new 出一个对象,简要的概括可以分为三步:
1.在堆上分配一块内存区域;
2.对象数据初始化;
3.将符号引用,指向堆内的实际内存地址 
而指令4和7会发生指令重排,在多线程中如果不加volatile修饰,如果发生指令重排,可以能会使用到半初始化对象,也就是说假如我第一个线程刚把对象创建完,里面的变量值还没初始化,只是赋了默认值,这时第二个线程在判断dclSingleton不等于空时,获取到的变量值可能是默认值,而不是我要设置的初始值。所以要加volatile修饰,禁止指令重排。需要等对象实例化完毕,建立了完整关系。

 

 

 

 

 

 

 

 

 

 

 

转载地址:http://uswmf.baihongyu.com/

你可能感兴趣的文章
利用栈实现DFS
查看>>
逆序对的数量(递归+归并思想)
查看>>
数的范围(二分查找上下界)
查看>>
算法导论阅读顺序
查看>>
Windows程序设计:直线绘制
查看>>
linux之CentOS下文件解压方式
查看>>
Django字段的创建并连接MYSQL
查看>>
div标签布局的使用
查看>>
HTML中表格的使用
查看>>
(模板 重要)Tarjan算法解决LCA问题(PAT 1151 LCA in a Binary Tree)
查看>>
(PAT 1154) Vertex Coloring (图的广度优先遍历)
查看>>
(PAT 1115) Counting Nodes in a BST (二叉查找树-统计指定层元素个数)
查看>>
(PAT 1143) Lowest Common Ancestor (二叉查找树的LCA)
查看>>
(PAT 1061) Dating (字符串处理)
查看>>
(PAT 1118) Birds in Forest (并查集)
查看>>
数据结构 拓扑排序
查看>>
(PAT 1040) Longest Symmetric String (DP-最长回文子串)
查看>>
(PAT 1145) Hashing - Average Search Time (哈希表冲突处理)
查看>>
(1129) Recommendation System 排序
查看>>
PAT1090 Highest Price in Supply Chain 树DFS
查看>>