对Java内存模型的理解

参考资料

@《深入理解Java虚拟机(第2版)》

@京东架构师100分钟带你重新认识Java内存模型!让你面试无忧!

@2019Java程序员必学-并发编程底层原理精讲视频全集 | 计算机硬件结构 | CPU多核缓存架构 | MESI | JMM

什么是Java内存模型?

Java内存模型的定义

Java内存模型【Java Memory Model - JMM】是Java虚拟机规范中用来屏蔽各种硬件和操作系统的内存访问差异的一组规范

Java内存模型的内容

1. 内存区域的划分

Java内存模型将内存区域划分为主内存【Main Memory】和工作内存【Working Memory】

Java内存模型规定所有的变量都存储在主内存中,而每个线程都有自己的工作内存工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读写)都必须在工作内存中进行,而不能直接操作主内存中的变量,且不同线程之间也无法直接访问对方线程的工作内存中的变量,线程间变量值的传递均需要通过主内存来完成

注意:这里的主内存和工作内存与Java虚拟机内存模型中的堆、栈、方法区等是不同层次的内存划分

2. 不同内存区域的数据交互协议

Java内存模型定义了8种基本原子操作1来实现主内存与工作内存的数据交互:

read:将变量的值从主内存传输到工作内存中
load:将read操作传输过来的值放入工作内存中的变量副本中
use:将变量副本的值传递给执行引擎
assign:将从执行引擎接收到的值赋给工作内存中的变量副本
store:将工作内存中变量副本的值传输到主内存中
write:将store操作传输过来的值放入主内存的变量中
lock:将变量标识为一条线程独占的状态
unlock:将处于锁定状态的变量释放出来

8种基本原子操作1的规则:

  1. read和load、store和write操作必须成对使用(即不允许只有read而没有load、只有store而没有write)、必须顺序执行(即不允许load在read之前、write在store之前)、可以不连续执行(即read和load之间可以有read和load、store和write之间可以有store和write)
  2. 一个变量在执行了assign操作之后(变量在工作内存中改变了),必须执行store和write操作(同步回主内存);如果没有执行过任何assign操作,则不允许执行store和write操作(同步回主内存)
  3. 一个变量在执行use操作、store操作之前必须先执行assign或load操作(即一个新变量只能在主内存中产生)
  4. lock和unlock操作必须有序执行(即只有先执行了lock操作才能执行unlock操作)、成对执行(即一个lock操作对应一个unlock操作);且一个变量在同一时刻只允许一个线程对其执行lock操作;一个变量如果执行了lock操作,那将会清空工作内存中此变量的值,在执行引擎使用该变量之前,需要重新执行load或assgin操作;对一个变量执行unlock操作之前,必须先将该变量同步回主内存中

2. 为什么需要JMM?

Java多线程并发情况下,由于多个线程之间数据不可实时可见,对于共享数据的操作存在竞争情况,可能导致出错

volatile关键字底层实现主要是通过汇编lock前缀指令,它会锁定这块内存区域的缓存(缓存行锁定)并回写到主内存

IA-32架构软件开发者手册对lock指令的解释:

  1. 会将当前处理器缓存行的数据立即回写到系统内存
  2. 这个回写内存的操作会引起其他CPU里缓存了该内存地址的数据无效(MESI协议)

  1. 对于double和long类型的变量来说,load、store、read和write操作在某些平台允许有例外 ↩︎ ↩︎

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值