https://www.imooc.com/article/19273?block_id=tuijian_wz
一、概述
关于现代CPU与Cache、RAM之间的数据与指令交互以及由此产生的一致性问题解决方案如MESI等这里就不说了,网上也有很多文章讲解到这些,这里说一下Java虚拟机的内存模型。
二、Java中的主内存与工作内存
1.主内存(Main Memory)
主内存可理解为Java虚拟机所拥有和管理的那一部分物理内存,所有的变量都存储于主内存中,这里的变量包括了实例字段、静态字段、数组元素,但不包括局部变量和方法的参数(因为这两者为线程私有)。
- 工作内存(Working Memory)
工作内存与Cahce类似,线程的工作内存中保存着该线程需要使用到的变量的副本,这些副本是从主内存拷贝而来。而线程对变量的所有操作都需要在工作内存中完成。- 工作内存与主内存之间的交互
Java虚拟机规范里面规定了8种原子操作来描述两者之间的数据交互,分别是: lock、read、load、use、assign、store、write、unlock;Java虚拟机规范里面明确指定了read和load操作、store和write操作这两组必须顺序执行,两者之间不能插入其他指令,也不允许这四个指令之一单独出现。类似的约束还有:assign操作使得工作内存中的数据的值发生改变,必须store到工作内存中并write到主内存,但是没有经过assign操作的数据,不能进行此操作。对一个变量执行use、store操作之前,必须先执行assign和load指令,以初始化变量。同一时刻只允许一个线程对一个变量执行lock操作,同一条线程也可以多次执行lock操作作用于同一个变量,但是一旦有线程对某一个变量执行了lock操作,那么之前存在于工作内存中的这个变量的值会被清空。执行引擎要是用这个变量的话,必须执行load或者assign。 - 关于volatile关键字
算是一个轻量级锁机制。为什么叫轻量级呢,因为被volatile关键字修饰的变量,依然是在各个线程的工作内存中保存了副本,可以出现每个线程工作内存中其值不一致的情况,但是每次使用volatile修饰的关键字的变量之前都要有一步刷新的动作,刷新之后对执行引擎来说看不到不一致的情况,因此呢,volatile修饰的关键字可以保持对其他线程的可见性,也即一旦某个线程修改了volatile修饰的一个变量的值,那么其他线程立即可见。所以可以确保被volatile修饰的关键字,在只有一个线程对其有写操作时,或者说不依赖这个变量当前值的时候,在各个线程的工作内存中不存在一致性问题。
- 工作内存与主内存之间的交互
作者:CaramelMacchiato
链接:https://www.imooc.com/article/19273?block_id=tuijian_wz
来源:慕课网