现代计算机的硬件结构:
CPU运行程序的时候需要从硬盘上读取数据,先把硬盘上的数据读到主内存上,然后再将数据加载到CPU缓存。在真正运行程序的时候CPU与CPU的高速缓存进行交互
Java的内存模型:
Java线程内存模型跟CPU缓存模型类似,是基于cpu缓存模型建立的,java线程内存模型是标准化的,屏蔽掉了底层不同计算机的区别
假设现在有A,B,C三个线程,同时运行,他们对内存的同一个共享变量进行操作,
底层的实现过程:
A,B,C会把共享变量从主内存分别拷贝一份到自己的工作内存中,然后去运行
假设A改变了共享变量的值对B,C而言是不可见 的
JMM数据原子操作:
- read(读取):从主内存读取数据
- load(载入):将主内存读取到的数据写入工作内存
- use(使用):从工作内存中读取数据来计算
- assign(赋值):将计算好的值重新赋值到工作内存中
- store(存储):将工作内存数据写入主内存
- write(写入):将store过去的变量赋值给主内存中的变量
- lock(锁定):将主内存变量加锁,标示为线程独占状态
- unlock(解锁):将主内存变量解锁,解锁后其他线程可以锁定该变量
解决JMM缓存不一致的问题:
总线加锁(性能太低):CPU从主内存读取数据到高速缓存,会在总线对这个数据加锁,这样其他的CPU没法去读或者写这个数据,知道这个CPU使用完数据释放锁之后其他CPU才能读取该数据
MESI缓存一致协议:多个CPU从主内存读取同一个数据到各自的高速缓存,当其中某个CPU修改了缓存里的数据,该数据会马上同步到主内存,其他CPU通过总线嗅探机制可以感知到数据的变化从而将自己缓存里的数据失效
Volatile
volatile:保证多线程访问共享副本之间的可见性
Volatile缓存可见性实现原理:
底层实现主要是通过汇编lock前缀指令,它会锁定这块内存区域的缓存(缓存行锁定)并返回到主程序
IA-32架构软件开发者手册会lock指令的解释
1.会将当前处理器缓存行的数据立即写回到系统内存
2.这个协会内存的操作会引起在其他CPU里缓存了改地址的数据无效(MESI协议)