计算机内存模型:缓存和主存通信方式的抽象;它用于解决cpu和主存读写效率问题;
优化计算机读写效率方式:
1 增加缓存:由于cpu读写速度要远远大于主存读写速度,所以通过缓存预读取数据来缩小cpu和主存的速度差异;
同时由于多核的原因,cpu可能会从主存中缓存多份数据,这样就造成了缓存数据一致性问题;
这里通过缓存一致性协议来解决缓存一致性问题;
缓存一致性协议:缓存数据不一致原因是多核造成了数据存在交叉读写的问题,如果将缓存和主存通信分成若干个原子性操作,
通过加解锁,约束读写顺序等操作,可以解决缓存间数据一致性问题;
2 乱序执行:减少执行阻塞,但是要对执行结果进行重组;
Java内存模型:
与计算机内存模型相似,Java内存模型通过定义程序中共享变量的访问规则,解决数据一致性问题,以提高cpu执行效率,屏蔽硬件和操作系统的内存访问差异,实现内存访问跨平台;
共享变量:线程共享的变量,包括全局变量,静态变量,构成数组对象的元素,不包括线程私有的局部变量和方法参数;
java内存模型:
主内存:Java虚拟机管理内存,包括:程序计数器,虚拟机栈,本地方法栈,堆,方法区;
工作内存:保存线程使用的变量副本,工作内存只能被自己的线程访问;
save和load操作:用于保证线程间数据一致性的协议;
内存中保证数据一致性的操作具体如下:
作用于主存中的变量的有: lock:将变量标记为线程独占; unlock:解除变量线程独占; read:将主存中变量读取到工作内存中,便于load使用; write:把store操作从工作内存中获取的变量写入主存的变量中; 作用于工作内存中的变量的有: load:把read操作中从主存中获取的变量放入工作内从中的变量副本中; use:将值传递给执行引擎,用于线程中操作; assign:给变量副本重新赋值; store:把工作内存的变量值传递给主存中,便于write操作使用
协议规则:
注意操作的有序性: 主内存->工作内存:read->load; 工作内存->主内存中:store->write; 以上操作有序,但是并不要求连续,可以在操作间加入其他操作; 不允许read和load、store和write操作之一单独出现 不允许一个线程丢弃它的最近assign的操作,即变量在工作内存中改变了之后必须同步到主内存中。 不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步回主内存中。 一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量。即就是对一个变量实施use和store操作之前,必须先执行过了assign和load操作。 一个变量在同一时刻只允许一条线程对其进行lock操作,lock和unlock必须成对出现 如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前需要重新执行load或assign操作初始化变量的值 如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量。 对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)。
参考资料:
<深入理解Java虚拟机(周志明)>