元月's blog 元月's blog
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多

元月

临渊羡鱼,不如退而结网
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多
  • 基础

  • 并发编程

    • 并发编程之JMM篇
    • JMM之volatile的底层实现原理详解
      • 一、简介
      • 二、volatile的作用
        • 1、volatile关键字保证可见性
        • 2、volatile禁止重排优化,volatile关键字来保证一定的“有序性”
      • 三、volatile的底层实现原理
        • 1、Java层面
        • 2、字节码层面
        • 3、JVM源码层面
        • 4、汇编语言层面
      • 四、思维导图
  • JVM

  • Java基础
  • 并发编程
元月
2022-08-08
目录

JMM之volatile的底层实现原理详解

# JMM之volatile的底层实现原理详解

# 一、简介

​ 从JDK 5开始,Java使用新的JSR-133内存模型,即JMM,提供了happens-before原则,其中有一条就是volatile规则,volatile变量的写,先发生于读,这保证了volatile变量的可见性。简单的理解就是,volatile变量在每次被线程访问时,都强迫从主内存中读该变量的值,而当该变量发生变化时,又会强迫将最新的值刷新到主内存,任何时刻,不同的线程总是能够看到该变量的最新值,

# 二、volatile的作用

# 1、volatile关键字保证可见性

​ 当对volatile变量执行写操作后,JMM会把工作内存中的最新变量值强制刷新到主内存写操作会导致其他线程中的缓存无效

# 2、volatile禁止重排优化,volatile关键字来保证一定的“有序性”

​ volatile是通过编译器在生成字节码时,在指令序列中添加“内存屏障”来禁止指令重排序的

​ 硬件层的内存屏障

  1. lfence,是一种Load Barrier 读屏障
  2. sfence, 是一种Store Barrier 写屏障
  3. mfence, 是一种全能型的屏障,具备ifence和sfence的能力
  4. Lock前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线和高速缓存加锁,可以理解为CPU指令级的一种锁

​ JVM内存屏障 ​ ​ 示例:非常典型的禁止重排优化的例子DCL

# 三、volatile的底层实现原理

# 1、Java层面

volatile修饰的Java变量,保证可见性和有序性

# 2、字节码层面

通过javap -v Test.class反编译查看字节码文件发现:

volatile在字节码层面,就是使用访问标志:ACC_VOLATILE来表示,供后续操作此变量时判断访问标志是否为ACC_VOLATILE,来决定是否遵循volatile的语义处理

# 3、JVM源码层面

​ 当对变量进行操作时,会判断is_volatile,如果是的话,会调用JVM层的内存屏障storeLoad。

# 4、汇编语言层面

JVM层的内存屏障storeLoad使用到了lock前缀指令,代码lock; addl $0,0(%%rsp)其中的addl $0,0(%%rsp)是把寄存器的值加0,相当于一个空操作(之所以用它,不用空操作专用指令nop,是因为lock前缀不允许配合nop指令使用)

lock前缀,会保证某个处理器对共享内存(一般是缓存行cacheline,这里记住缓存行概念,后续重点介绍)的独占使用。它将本处理器缓存写入内存,该写入操作会引起其他处理器或内核对应的缓存失效。通过独占内存、使其他处理器缓存失效,达到了“指令重排序无法越过内存屏障”的作用(MESI)

# 四、思维导图

#volatile#JMM#可见性#有序性#指令重排
并发编程之JMM篇
Java的调试体系-JPDA架构

← 并发编程之JMM篇 Java的调试体系-JPDA架构→

最近更新
01
otter二次开发-支持按目标端主键索引Load数据
08-03
02
mvnw简介
06-21
03
gor流量复制工具
06-03
更多文章>
Theme by Vdoing | Copyright © 2022-2024 元月 | 粤ICP备2022071877号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式