JMM模型是什么?
Java内存模型(Java Memory Model简称JMM)是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。需要JVM的实现都需要遵守这样的规范,有了JMM规范的保bujj,并发程序运行在不同的虚拟机上时,所得到的程序结果才是安全可靠可信赖、不同JVM运行结果一致。
百度百科:
https://baike.baidu.com/item/java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/3399303
个人理解:比如读大学的时候有来自全国各地(不同硬件厂商、操作系统),但是只要是属于这个大学的学生,由学校统一安排(屏蔽差异)好每个人的学号(线程id)、教室(运行)、住宿(存储空间)等。
JMM主要解决什么问题?
由于我们软件是运行于硬件上面的,但是各大厂的硬件有所区别,导致可能在三星主板上和微星上面可能有所不一样,还有在windows、linux等系统上的系统上面所支持内存访问也有所区别,导致可能出现不一样的结果。由于java是跨平台的,基于这些差异,保证了java程序在各种平台下对内存的访问都能保证一致的执行结果,所以引入了JMM来屏蔽掉各种硬件和操作系统的内存访问差异,实现让java程序在各种平台下都通达到一致的内存访问效果。
当然由于JMM也存在共享数据区域,所以就会存在数据的 原子性、可见性、有序性。JMM通过java提供的 volatile解决可见性、通过synchronized和lock来解决有序性,那么原子性通过锁的方向进行实现。
JMM三大特性:原子性、可见性、有序性
原子性:一个或多个操作,要么全部成功,要么全部失败(不会存在中间状态);
可见性:指的修改了某个共享变量的值,其他线程可以立即获取到最新值;
有序性:指程序按照顺序从上到下,从左至右执行;
什么是happens-before 原则?
Happens-before是一个概念,一种现象,或者仅仅是一组规则,它定义了编译器或CPU对指令进行重新排序的基础。Happens-before不是Java语言中的任何关键字或对象,它只是一种规则,以便在多线程环境中,周围指令的重新排序不会导致代码产生不正确的输出。
happens-before 规定如下:
在java中从源码到最终执行会经历(源代码->编译器优化重排序->指令级并行重排序->内存系统重排序->最终执行的批评令序列)。jdk5开始,java使用新的JSR-133内存模型,其中就包括Happens-before,从而来辅助JMM中有序性通过通过硬件层面的as-if-serial来标识不让执行结果改变,来保证结果的一致性。
注意:volatile是禁止重排优化的。
参考:
https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html
https://www.geeksforgeeks.org/happens-before-relationship-in- java/#:~:text=Happens-before%20is%20not%20any%20keyword%20or%20object%20in,result%20in%20a%20code%20that%20produces%20incorrect%20output.
https://dzone.com/articles/happens-before-in-java-or-how-to-write-thread-safe
主内存与工作内存有什么区别?
主内存:主要用于存储的是java实例的对象,所有线程创建的实例对象都存放在这里,当然包括实例对象、成员变量、方法中的本地变量(局部变量)、静态变量、常量、及共享的类信息,往往这里存在多个线程同时访问和操作导致的线程安全问题。
工作内存:主要指的是线程从主内存拷贝使用到的变量副本,仅线本线程使用,其他线程不可见。
个人理解:主内存类似于露天停车场,大家都可以用(共用),工作内存类似于自已私有停车场(专用),当然这个有可能是租的,就是公共里面一些又特别收费的,呵呵~。
JMM的规定、操作及规则
规定
操作
规则
JMM不同于jvm模型有什么区别?
对比名称 | JMM | jvm内存 |
---|---|---|
解决问题 | 原子性、有序性、可见性展开 | 对象内存开辟及生命周期 |
划分区别 | 工作区和公共内存数据区域 | 方法区、堆、JVM栈、本地方法栈、程序计数器 |
最后
根据JMM来了解java其实对于内存的操作有一个严格的标准规则,就类似于我们汽车在路上要遵循交通规则一样来约束我们安全驾驶,特别是这happens-before的使用很层使JMM的有序性得到进一步的保障。当然本人只讲JMM其时还有内存屏障未写到,考虑到篇幅原因后续再完善,有想再深入同学可以先了解一下cpu多级缓存以及下面的一些参考文章。
参考文章:
https://www.cs.umd.edu/~pugh/java/memoryModel/
https://blog.csdn.net/LYQ20010417/article/details/124138635
https://segmentfault.com/a/1190000017395235
https://zhuanlan.zhihu.com/p/372288168
https://blog.csdn.net/GarfieldEr007/article/details/83315848
https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html
https://lamport.azurewebsites.net/pubs/time-clocks.pdf