主内存的数据会被加载到cpu本地缓存里去,cpu后面会读写自己的缓存
缓存模型下的并发问题
java内存模型
read(从主存读取),load(将主存读取到的值写入工作内存),use(从工作内存读取数据来计算),assign(将计算好的值重新赋值到工作内存中),store(将工作内存数据写入主存),write(将store过去的变量值赋值给主存中的变量)
volatile保持内存可见的原理
就是说一定会强制保证说assign之后,就立马执行store + write,刷回到主内存里去。并且将其他工作内存中的状态改为过期
volatile无法保持原子性的原理
2个线程同时use后,线程1assign了以后,刷回了主内存。但线程2已经use了,不需要在从内存中加载。此时使用的旧的值。
底层使用cpu的MESI缓存一致性协议,强制刷主内存,过期其他线程中的工作内存
volatile内存屏障及happen before原则
在被volatile标记的字段读写前后都设置内存屏障,防止指令重排。
指令重排的happen before原则,是给开发JVM的人看的。
大概有几个原则
程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
lock规则:一个unLock操作先行发生于后面对同一个锁的lock操作
volatile变量规则:必须保证是先写,再读
volatile的实际用途和场景
double check的单例模式,使用volatile防止指令重排
instance=new Singleton() 分为3步
1、volatile保证并发可见性
2、synchronized保证有序性
3、double check保证对象被正常创建(类加载创建过程多线程问题)
|
|