首页 > 其他 > 详细

JMM

时间:2021-04-02 17:42:11      阅读:50      评论:0      收藏:0      [点我收藏+]

JMM java memary model java内存模型)

一、CPU架构缓存一致性

技术分享图片

 

 

 

现在计算机都加高级缓存,让运算速度加快,在运算过程中把某些变量放到高级缓存里面,等运算结束以后,再从高级缓存同步到内存中,这样避免IO读写过慢CPU的空闲。

 

加入高级缓存会带来问题,带来缓存一致性的问题,在多线程情况下,看不见已经修改的变量的值。最初的解决方案就是总线锁的方式,总线锁性能比较低,多个CPU出现竞争,有的cpu出现空闲等待。

 

现在的cpu是基于缓存一致性协议实现的内存模型。最出名的缓存一致性协议internet mesi,共享变量a在处理器都存在副本,如果变量被某一个处理器改了会发出信号告诉其他的CPU置成无效的。

 

1、缓存一致性协议

 

缓存一致性协议给缓存行(通常为64字节)定义了个状态,用来描述该缓存行是否被多处理器共享、是 否修改,缓存一致性协议最出名的是mesi。

 

独占:仅当前处理器拥有改缓存行

 

共享:多个处理器拥有该缓存行,每个处理器都没修改过缓存值。

 

修改:仅当前处理器拥有改缓存行,并且缓存行被修改过。

 

失效:缓存行被其它处理器修改过,不是最新的,就会变成失效状态,重新读取值。

 

二、CPU相关术语

 

内存屏障:Memory barriers 是一组处理器指令,用于实现对内存操作的顺序执行。

 

缓存行:Cache line 缓存中可以分配的最小存储单位

 

三、原子性、可见性、有序性

 

1、原子性:readloaduseassignstorewritelockunlock 8个汇编指令。Monitorenter monitorexit。线程之间互不影响,不被中断。

 

2、可见性:一个线程操作的变量对其它线程可见

 

3、有序性:线程内都是有序的,线程内观察别的线程都是无序的。

 

四、JMM模型

 

1、工作内存中,线程A改了对线程B不可见。

 

 

 技术分享图片

 

2、JMM内存模型分析

Read 从主内存里读出来,load载入,作用于工作内存,从内存读的值放到工作变量里。User 作用于工作内存,把变量传递给执行引擎(cpu)。Assign 赋值,主要作用于工作内存。Store存储,主要作用于工作内存。Write 主要作用于主内存。

技术分享图片

3、指令重排

技术分享图片

 

 

编译器重排序:不改变单线程执行结果的前提,对语句执行顺序进行优化。

指令级并行重排序:采用并行技术ilp,多条指令的重叠执行。

内存系统得重排序:处理器使用缓存和读写缓存序列,使我们的加载存储操作是乱序执行的,as if serial单线程语义规则。

4、Happens-before

只是一个概念

技术分享图片

5、内存屏障

1)阻止屏障两侧的指令重排序

2)强制把写缓存去/高速缓存区的脏数据写回主内存,让缓存中响应的数据失效。

JSR规范中定义了4种内存屏障:

? LoadLoad屏障:(指令Load1; LoadLoad; Load2),在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

? LoadStore屏障:(指令Load1; LoadStore; Store2),在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕

? StoreStore屏障:(指令Store1; StoreStore; Store2),在Store2及后续写入操作执行前,保证Store1 的写入操作对其它处理器可见

? StoreLoad屏障(比较常用):(指令Store1; StoreLoad; Load2),在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。

Jdk源码地址

https://github.com/openjdk/jdk

看汇编时需要下载一个软件 hisdis 下载dll 放在jre下面的lib下面,下载jclasslib bytecode Viewer插件,通过这个插件可以看class的字节码。下载JITWatch 看汇编

技术分享图片

 

 技术分享图片

6、Volatile

用StoreLoad 内存屏障,防止指令重排序。

技术分享图片

 

 

五、可见性

1、加了volatile,有lock就总线嗅探,如果发生变化,使自己的变量失效,重新加载

技术分享图片

 

 

2、单例的双重检索,这样写的好处是,延迟初始化来降低初始化类和创建对象的一个开销。

技术分享图片

 

 

使用单例模式,如果没有加volatile,会有指令重排序,导致拿到的instance为空,而报错。

 技术分享图片

 

 

六、CAS

独占锁是一种悲观锁,synchronized就是一种悲观锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放。

乐观锁是一种更加有效的锁,每次不加锁,而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。

技术分享图片

 

 

cmpxchg是汇编指令
作用:比较并交换操作数

2、问题:以下counter的输出小于20万,并且一般情况下小于20万。Counter的操作不具有原子性。

技术分享图片

 

 

AtomicInteger 共享变量包装类。使变量变为原子性。

While自旋,直到成功为止。

技术分享图片

 

 技术分享图片

 

 

 

 

 

JMM

原文:https://www.cnblogs.com/majingyun/p/14610270.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!