java基础-volatile关键字原理

volatile的作用

之前写过日志记录了volatile的关于可见性的用法,也是最常见的用法。其实volatile还有一个比较常用的使用方法就是可以防止重排序。回忆一下对象的构造过程,即实例化对象的步骤(关于jvm部分后面会记录周志明老师的深入理解JAVA虚拟机的读书笔记):

  • 分配内存空间
  • 初始化对象
  • 将内存空间的地址复制给对象的引用

但是根据JMM的规范,jvm不会干预操作系统对指令可能进行的重排序,所以上面的过程第二条和第三条有机会发生顺序的颠倒,那么在这个情况下就会将会复制的对象的引用暴露出来。因此为了防止这个过程的重排序,我们需要将变量设置成volatile类型。

volatile的原理

  • 可见性实现:

    线程本身并不直接与主内存进行数据的交互,而是通过线程的工作内存来完成相应的操作。这也是导致线程间数据不可见的本质原因。因此要实现volatile变量的可见性,直接从这方面入手即可。对volatile变量的写操作与普通变量的主要区别有两点:

    • 修改volatile变量时会强制将修改后的值刷新的主内存中。

    • 修改volatile变量后会导致其他线程工作内存中对应的变量值失效。因此,再读取该变量值的时候就需要重新从读取主内存中的值。

      通过这两个操作,就可以解决volatile变量的可见性问题。

  • 有序性实现

    即为文章开始时写的,JMM会对volatile变量限制操作系统的重排序。

  • 内存屏障

    为了实现volatile的可见性和有序性,JVM使用了一组叫做内存屏障(内存栅栏)的处理器指令。这些指令还不是很明白,后续再研究。

坚持原创技术分享,您的支持将鼓励我继续创作!

热评文章