首页 > 其他 > 详细

DCL单例为什么要加Volatile

时间:2020-05-20 13:11:46      阅读:108      评论:0      收藏:0      [点我收藏+]

拿一个对象创建赋值来说

class T{
  int  elem = 1;
}

T t = new T();

上段代码转换成汇编码为:

0  new  #2 <T>
3  dup
4  invokespecial  #3  <T.<init>>
7  astore_1
8  return 

从汇编码中可以看出,0行为对象开辟了一个内存空间,该内存的成员区包含整形变量elem,值初始为0(如果是引用或者指针变量则为空)。3行dup指令是在栈中复制一个对象的引用(在new的时候该栈中已经存在一个,执行dup后也就是两个了),第4行执行初始化,为对象成员变量赋值,这个时候会消耗一个引用并将它从栈中pop掉,这也是为什么要dup的原因。7行指令是将栈中的引用赋值给对象t,并在栈中pop掉该引用。8然后return。这个是整个汇编语言按源代码执行得过程。

但是cpu本质上得乱序执行,可能造成指令得重排,特别是在初始化对象指令上花费时间较多,可能进行了如下重排:

0  new  #2 <T>
3  dup
7  astore_1
4  invokespecial  #3  <T.<init>>
8  return 

指令第7行可能在cpu执行是与第4行重排,那么当线程一从0开始执行,执行到第7行得时候将未初始化得对象得引用赋值给t,如果线程一挂起,线程二发现t的引用不为空在执行下面代码:if (t != null)  xxxx->使用了半初始化得对象。会造成后续程序出错。所以用volatile来禁止指令重排来保证单例线程安全。

技术分享图片

 

DCL单例为什么要加Volatile

原文:https://www.cnblogs.com/lhdeng1991/p/12922451.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!