什么是JMM?
这里需要引出了一个Java内存模型(JMM)的概念了,JMM是一个抽象模型,它是建立在不同的操作系统和硬件层面之上,对问题进行了统一的抽象。
JMM定义了共享内存中多线程程序读写操作的行为规范:在虚拟机中把共享变量存储到内存以及从内存中取出共享变量的底层实现细节。通过这些规则来规范对内存的读写操作从而保证指令的正确性,它解决了CPU多级缓存、处理器优化、指令重排序导致的内存访问问题,保证了并发场景下的可见性。
JMM内存模型机构
相信大家对下面这个图不陌生,我们总说主内存与CPU工作内存,CPU将主内存中的变量读取到工作内存,保存一个变量副本,修改这个变量的值后,最终会写回主内存,那么主内存和CPU的工作内存到底是怎么交互的呢?
JMM是如何控制CPU工作内存和主内存间的交互呢?看下面一张图
read(读取): 读取主内存的数据
load(载入): 将读取的数据写入工作内存
use(使用): 使用工作内存的变量副本
assign(赋值): 将新的值赋给工作内存中的变量
store(存储): 将工作内存变量写入主内存
write(写入): 将store过去的新的值赋给主内存变量
lock(加锁): 将主内存变量加锁,设置为独占状态
unlock(解锁): 将主内存变量解锁,其他线程可以对变量加锁
总结
需要注意的是,JMM是一个抽象模型,它是建立在不同的操作系统和硬件层面之上对问题进行了统一的抽象,在JMM这个模型之上,仍然会存在缓存一致性问题和指令重排序问题。在Java层面提供了一些高级指令,让用户选择在合适的时候去引入这些高级指令来解决可见性和有序性问题。
通过前面的内容分析我们发现,导致并发安全性问题有两个因素,一个是高速缓存导致的可见性问题,另一个是指令重排序。
那JMM是如何解决可见性和有序性问题的呢?
其实前面在分析硬件层面的内容时,已经提到过了,对于缓存一致性问题,有总线锁和缓存锁,缓存锁是基于MESI协议。而对于指令重排序,硬件层面提供了内存屏障指令。 而JMM在这个基础上提供了volatile、final等关键字,使得开发者可以在合适的时候增加相应相应的关键字来禁止高速缓存和禁止指令重排序来解决可见性和有序性问题。
本文是综合自己的认识和参考各类资料(书本及网上资料)编写,若有侵权请联系作者,所有内容仅代表个人认知观点,如有错误,欢迎校正; 邮箱:1354518382@qq.com 博客地址:https://blog.csdn.net/qq_35576976/