Java 内存模型(Java Memory Mode ,JMM)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Stu_zkl/article/details/82714354

JMM定义

Java内存模型(Java虚拟机规范中定义):屏蔽掉各种硬件和操作系统之间内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果

计算机中的并发问题

在正式了解JMM之前,先了解下计算机中怎么解决并发问题

由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器的运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲:将运算需要使用到的数据复制到缓存中,让运算能快速进行,当运算结束再从缓存同步回内存之中,这样处理器就无须等到缓慢的内存读写了

but,正因为这样它引入了一个新的问题,缓存一致性(Cache Coherence)。

image_1cjcmkluldtc47m17841mmf44i9.png-47.8kB

在多核计算机中,每个处理器都有自己的高速缓存,而它们共享同一个内存。当运算任务都涉及同一块内存区域时,将可能导致各自的缓存数据不一致,那这是同步回内存时,就出问题了。。

所以为了解决一致性问题,各个处理器访问缓存时都遵循一些协议,在读写时要根据协议来继续操作,这类协议有MSI、MESI、MOSI、Synapse、Firefly、DragonProtocol

image_1cjco0rjfn802731v8v11hgl5g26.png-30.9kB

JMM 与 计算机中内存访问操具有很高的可比性

主内存与工作内存

JMM规定了所有的变量都存储在主内存(Main Memory)中。每个线程还有自己的工作内存(Working Memory),线程的工作内存中保存了该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量(volatile变量仍然有工作内存的拷贝,但是由于它特殊的操作顺序性规定,所以看起来如同直接在主内存中读写访问一般)。不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。

image_1cjco8u3316gkc8qnsgvb11hj530.png-59.1kB

Java内存模型中定义了8中操作来完成主内存与工作内存之间具体的交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节

- lock(锁定): 作用于主内存的变量, 它把一个变量标识为一条线程独占状态。
- unlock (解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
- read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用。
- load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
- use(使用):作用于工作内存的变量,它把工作内存中的一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用的变量的值的字节码指令时将会执行这个操作。
- assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量,每当虚拟机遇到一个变量赋值的字节码指令时执行这个操作。
- store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的write操作使用。
- write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量值放入主内存的变量中。

所以
如果要把一个变量从主内存复制到工作内存,那就顺序执行read和load操作。
如果要把一个变量从工作内存同步到主内存,那就顺序执行store和write操作。

猜你喜欢

转载自blog.csdn.net/Stu_zkl/article/details/82714354