并发源码| JMM与volatile
主内存的数据会被加载到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保证对象被正常创建(类加载创建过程多线程问题)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public Singleton getInstance(){
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance=new Singleton();
}
}
}
return instance;
}
}
- 原文作者:
- 原文链接:https://leyou240.github.io/post/juc01_java%E5%B9%B6%E5%8F%91_jmm%E4%B8%8Evolatile/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。