目录
前置知识:内存屏障
什么是内存屏障
内存屏障是一种指令,无论是在JAVA内存模型还是CPU层次,都是有具体的指令对应的,是一种特殊的指令。
作用
这种指令具有屏障的作用,所谓屏障,也就是类似关卡,类似栅栏,具有隔离的作用。
内存屏障的分类
- 强制读取主内存,强制刷新主内存的内存屏障,叫做Load屏障和Store屏障
- 禁止指令重排序的内存屏障,有四个分别叫做LoadLoad屏障、StoreStore屏障、LoadStore屏障、StoreLoad屏障
1. 强制读取/刷新主内存的屏障
Load屏障:执行读取数据的时候,强制每次都从主内存读取最新的值。
Store屏障:每次执行修改数据的时候,强制刷新回主内存。
强制刷新主内存:Load屏障
如上图所示:在工作内存的变量名、变量的值之前有一道关卡或者栅栏,导致变量 i 获取不到工作内存中的值,所以每次只好主内存重新加载咯。
强制读取主内存:Store屏障
如上图所示,每次执行assign指令将数据变更之后,后面都会紧紧跟着一个Store屏障,让你立刻刷新到主内存。
总结
只要加了Load屏障,相当于加了一个栅栏,不管工作内存是否有数据,都是从主内存读取数据。只要加了Store屏障,具有强制作用,进行assign操作将变量更改了之后,立刻将变量刷新到主内存
2. 禁止指令重排序的屏障
LoadLoad屏障
序列:load1指令 LoadLoad屏障 load2指令
作用:在load1指令和load2指令之间加上 LoadLoad屏障,强制先执行load1指令再执行load2指令;load1指令和load2指令不能进行重排序(LoadLoad屏障 前面load指令禁止和屏障后面的load指令进行重排序)。
StoreStore屏障
序列:store1指令 StoreStore屏障 store2指令
作用:在store1指令和store2指令之间加上StoreStore屏障,强制先执行store1指令再执行store2指令;store1指令不能和store2指令进行重排序(StoreStore屏障 前面的store指令禁止和屏障后面的store指令进行重排序)
LoadStore屏障
序列:load1指令 LoadStore屏障 store2指令
作用:在load1指令和store2指令之前加上LoadStore屏障,强制先执行load1指令再执行store2指令;load1指令和store2执行不能重排序(LoadStore屏障 前面的load执行禁止和屏障后面的store指令进行重排序)
StoreLoad屏障
序列:store1指令 StoreLoad屏障 load2指令
作用:在store1指令和load2指令之间加上StoreLoad屏障,强制先执行store1指令再执行load2指令;
store1指令和load2指令执行不能重排序(StoreLoad屏障 前面的Store指令禁止和屏障后面的Store/Load指令进行重排)
以StoreStore屏障和StoreLoad屏障举个例子
(1)有三个区域分别是区域1、区域2、区域3
(2)区域1和区域2加了 StoreStore屏障,这样区域1和区域2的Store指令就被隔离开来,不能重排了
(3)区域2和区域3加了StoreLoad屏障,这样区域2和区域3的Store指令、Load指令就被隔离开来,不能重排了
(3)就相当于搞了个栅栏,禁止各个区域之间的指令跳来跳去的,否则就会导致乱序执行