JMM(JavaMemoryModel)
2022-03-19 00:40:53 0 举报
AI智能生成
Java 内存模型
作者其他创作
大纲/内容
CPU缓存一致性MESI
这里只是缓存行Cache line操作
如果数据大于缓存行会变成总线锁
如果数据大于缓存行会变成总线锁
缓存行伪共享
例子
怎么解决伪共享?
@sun.misc.Contended
MESI优化和他们引入的问题
CPU切换状态阻塞解决-存储缓存(Store Bufferes)
Store Bufferes
Store Bufferes的风险
硬件内存模型
介绍
图形理解
JMM模型
主内存
工作内存
与硬件内存架构
存在的必要性
在不同平台都可运行
同步问题
JMM模型产生的同步问题
八大原子操作
lock 锁定
unlock 解锁
read 读取
load 载入
use 使用
assing 赋值
store 储存
write 写入
同步规则分析
并发编程问题
原子性
解决
synchronized
Lock
思路同一时间只有一个线程访问
可见性
发生的原因
JMM线程私有的工作空间和主内存不实时同步
解决
volatile
原理:共享变量修改实时同步,其他线程立马读取
内存语义
保证被volatile修饰的共享变量对所有线程总数可见的,也就是当一个线程修改了一个被volatile修饰共享变量的值,新值总是可以被其他线程立即得知。
禁止指令重排序优化。
注意:无法保证原子性
实现
内存屏障
有序性
原因
指令重排
as-if-serial语义
解决
Java内存模型
happens-before 原则
volatile
sychronized
内存屏障
Intel硬件提供了一系列的内存屏障,主要有:
lfence
sfence
mfence
Lock前缀 并非内存屏障
不同硬件的实现不同java内存模型屏蔽
这种底层硬件平台的差异,由JVM来为
不同的平台生成相应的机器码。 JVM中
提供了四类内存屏障指令:
这种底层硬件平台的差异,由JVM来为
不同的平台生成相应的机器码。 JVM中
提供了四类内存屏障指令:
LoadLoad
Load1; LoadLoad; Load2
保证load1的读取操作在load2及后续读取操作之前执行
StoreStore
Store1; StoreStore; Store2
在store2及其后的写操作执行前,保证store1的写操作已刷新到主内存
LoadStore
Load1; LoadStore; Store2
在stroe2及其后的写操作执行前,保证load1的读操作已读取结束
StoreLoad
Store1; StoreLoad; Load2
保证store1的写操作已刷新到主内存之后,load2及其后的读操作才能执行
作用
1 是保证特定操作的执行顺序
2 是保证某些变量的内存可见性
(利用该特性实现volatile的内存可见性)
(利用该特性实现volatile的内存可见性)
代码例子
描述
因为instance = new DoubleCheckLock();
可以分为以下3步完成(伪代码)
可以分为以下3步完成(伪代码)
memory = allocate();//1.分配对象内存空间
instance(memory);//2.初始化对象
instance = memory;//3.设置instance指向刚分配的内存地址,此时instance!=null
instance(memory);//2.初始化对象
instance = memory;//3.设置instance指向刚分配的内存地址,此时instance!=null
由于步骤1和步骤2间可能会重排序,如下:
memory=allocate();//1.分配对象内存空间
instance=memory;//3.设置instance指向刚分配的内存地址,此时instance!=null,但是对象还没有初始化完成!
instance(memory);//2.初始化对象
instance=memory;//3.设置instance指向刚分配的内存地址,此时instance!=null,但是对象还没有初始化完成!
instance(memory);//2.初始化对象
问题
另外的线程用memory调用但是没有instance没初始化就会出现一些问题
解决
//禁止指令重排优化
private volatile static DoubleCheckLock instance;
private volatile static DoubleCheckLock instance;
0 条评论
下一页