一.概述
java内存模型(简称JMM),定义了线程和工作内存的一种抽象关系,即JMM 定义了 JVM 在内存中的工作方式。其和内存区域不一样,内存区域定义的是JVM的内存划分,即运行时数据区,包括堆、栈、程序计数器、方法区。
二.什么是java内存模型
java内存模型是java 共享变量的并发读写模型。JMM控制线程之间的通信,决定一个线程何时对共享变量可见。
三.JVM主内存与工作内存
JMM 定义了所有变量都存在主内存,每个线程有自己的工作内存,工作内存存储变量的副本,线程对变量的所有操作必须在工作内存进行,而不能直接读写主内存。

这里的主内存相当于JVM中的堆,工作内存相当于虚拟机栈部分
四.重排序
在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序。重排序分三种类型:
1.编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
2.指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-Level Parallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
3.内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。
四.内存屏障
共享变量在线程之间的可见性就是通过内存屏障完成的。java有四种屏障类型,分别是LoadLoad Barriers,StoreStore Barriers,LoadStore Barriers,StoreLoad Barriers。
1.2、LoadLoad Barriers
简单的理解就是当有两个Load,一个Load1一个Load2,Load1加载代码要从内存里面读取的数据读取完毕之后,Load2加载代码才能读取数据。
1.3、StoreStore Barriers
理解为当有两个Store,一个是Store1一个是Store2,Store1的写入操作已经把数据写入到内存里面,并且保证Store1的写入操作对其它处理器可见之后,才会对Store2存储代码进行写入操作执行。
1.4、LoadStore Barriers
理解为当有一个Load1和一个Store2,要先保证Load1加载代码要从内存里面读取的数据读取完毕之后,Store2存储代码才会进行写入操作。
1.5、StoreLoad Barriers
理解为当有一个Store1和Load2,要先保证Store1的写入操作已经把数据写入到内存里面,并且确认Store1的写入操作对其它处理器可见,Load2加载代码才从内存里面读取数据。而且因StoreLoad Barriers同时具备其他三个屏障的效果,因此也称之为全能屏障,是目前大多数处理器所支持的,但是相对其他屏障,该屏障的开销相对昂贵的。
内存屏障在volatile中的作用
在每个volatile写操作前插入StoreStore屏障,这样就能让其他线程修改A变量后,把修改的值对当前线程可见,在写操作后插入StoreLoad屏障,这样就能让其他线程获取A变量的时候,能够获取到已经被当前线程修改的值
在每个volatile读操作前插入LoadLoad屏障,这样就能让当前线程获取A变量的时候,保证其他线程也都能获取到相同的值,这样所有的线程读取的数据就一样了,在读操作后插入LoadStore屏障;这样就能让当前线程在其他线程修改A变量的值之前,获取到主内存里面A变量的的值。
参考 https://blog.csdn.net/ChineseSoftware/article/details/119212455
https://blog.csdn.net/qq_48241564/article/details/122433626