volitale 关键字

余生长醉 提交于 2020-02-21 04:16:41

一、前言

volitale 知识点主要涉及JAVA内存模型的知识点,volitale提供了内存可见性和禁止指令重排的功能。

参考文章:https://blog.csdn.net/eff666/article/details/67640648

二、知识点

1.内存可见性

        对变量进行访问和赋值时,观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令。lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:

     (1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;

     (2)它会强制将对缓存的修改操作立即写入主内存;

     (3)如果是写操作,它会导致其他CPU中对应的缓存行无效。

        处理器为了提高处理速度,不直接和内存进行通讯,而是将系统内存的数据独到内部缓存后再进行操作,但操作完后不知什么时候会写到内存。

如果对声明了volatile变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写会到系统内存。这一步确保了如果有其他线程对声明了volatile变量进行修改,则立即更新主内存中数据。

但这时候其他处理器的缓存还是旧的,所以在多处理器环境下,为了保证各个处理器缓存一致,每个处理会通过嗅探在总线上传播的数据来检查 自己的缓存是否过期,当处理器发现自己缓存行对应的内存地址被修改了,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作时,会强制重新从系统内存把数据读到处理器缓存里。 这一步确保了其他线程获得的声明了volatile变量都是从主内存中获取最新的。

2.禁止指令重排

  • 禁止指令重排的概念是:使用volitale变量所在代码作为一个界限,其前面的代码不能重新调整到后面,后面的也不能调整到前面。但是不能保证其前面的代码不会出现重新排序的情况,后面也是一样。
  • volitale 通过内存屏障实现 禁止指令重排
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!