并发编程情况下有三个要点:操作的原子性、可见性、有序性。

volatile保证了可见性和有序性,但是并不能保证原子性。

首先看一下DCL(双重检验锁)的实现:

public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
  if (singleton == null) {
  singleton = new Singleton();
  }
}
}
return singleton;
}
}

无论是volatile修饰singleton 还是 synchronized 还是两次是否未null的判断,都是为了保证 new 操作的正常进行

所以new操作的背后到底有什么秘密的?

new 实例背后的指令

从字节码可以看到创建一个对象实例,可以分为三步:

  1. 分配对象内存
  2. 调用构造器方法,执行初始化
  3. 将对象引用赋值给变量。

虚拟机实际运行时,以上指令可能发生重排序。以上代码 2,3 可能发生重排序,但是并不会重排序 1 的顺序。也就是说 1 这个指令都需要先执行,因为 2,3 指令需要依托 1 指令执行结果。

虽然重排序并不影响单线程内的执行结果,但是在多线程的环境就带来一些问题。

在JIT里,可能会将2与3进行重排序,在单线程里这里并不会发生什么问题,但是在多线程情况下,会出现下面的问题

时间

线程A

线程B

t1

A1:分配对象的内存空间

 

t2

A2:设置singleton指向内存空间

 

t3

 

B1:判断singleton是否为空

t4

 

B2:由于singleton不为null,线程B将访问singleton引用的对象

t5

A3:初始化该对象(使得singleton不为空)

 

t6

A4:访问singleton引用的对象

 

 

A2与A3重排序后,会让线程B在B1处判断出singleton不为null,线程B接下来将访问的singleton引用的对象是一个未初始化的对象。

所以用volatile修饰 singleton来就是禁止2与3的重排序,来保证线程安全的延迟初始化。

参考链接:https://blog.csdn.net/OrangeRawNorthland/article/details/83788412

最新文章

  1. 每天一个linux命令(33):df 命令
  2. eclipse中整合springMvc,velocity和sitemesh
  3. 重放攻击(Replay Attacks)
  4. WCF多种调用方式兼容
  5. 用CSS做长度超过长度显示‘...’,当鼠标放上时显示全部内容
  6. ASP.NET Web API路由规
  7. centos增加网卡
  8. 给LinkLabel文本绘制颜色
  9. spring的配置模式与注解模式基础
  10. 方格取数(1)(HDU 1565状压dp)
  11. Libnids---编写网络应用程序的利器
  12. :after/:before使用技巧
  13. Python内置函数(60)——compile
  14. Can not issue data manipulation statements with executeQuery()错误解决
  15. CloudSim源代码学习——虚拟机(VM)
  16. [C++基础]队列<queue>中的常用函数
  17. 团队作业8-测试与发布(beta阶段)
  18. 查询过的问题关于HTML的问题
  19. excel 妙用选择性粘贴
  20. Webform和MVC,为什么MVC更好一些?(转)

热门文章

  1. idea中类注释和方法注释的设置
  2. StringTable---字符串常量池的垃圾回收跟踪案例
  3. NodeMCU学习笔记
  4. WPF 之 INotifyPropertyChanged 接口的使用 (一)
  5. spring源码学习笔记之容器的基本实现(一)
  6. Windows下使用poetry和pyproject.toml
  7. JavaScript里处理数组的一些常用方法
  8. Codeforces Round #652 (Div. 2) E. DeadLee 贪心
  9. L3-002 特殊堆栈 (30分) vector容器的模拟、vector容器的一些用法
  10. springboot demo(一)快速开始