java 的内存模型的理解
java的内存模型是一种抽象,对java 语言在不同硬件平台上运行的差异的一种抽象描述,目的是屏蔽不同硬件平台之间的差异。
JMM定义了线程和主存之间的访问模式: 同一个进程的所有线程共享的变量存于主存中,每个线程有一个该变量的副本。
实际上,在计算机内存架构设计实践中,每个CPU 有自己独享的cache,主流的CPU有3级缓存: L1,L2, L3 cache;其中L1, L2 属于每颗cpu, L3 为多个cpu共享。
参考文献: https://blog.csdn.net/qq_35958391/article/details/124364296
本质上, JMM并不是真实存在的,而是多线程协同工作的一组规范而已!!!需要具体的JVM 实现其语义,这样同一程序在不同平台上的结果才是一致的。
volatile、synchronized、final等,它们的实现原理都涉及 JMM。有了 JMM 的参与,才让各个同步工具和关键字能够发挥作用同步语义才能生效,使得我们开发出并发安全的程序。主要目的就是让 Java 程序员在各种平台下达到一致性访问效果。
重排序、有序性、原子性、可见性概念
参考文献:https://tobebetterjavaer.com/sidebar/sanfene/javathread.html#_19-说说你对原子性、可见性、有序性的理解
-
重排序:
为了取得更加高效的运行效率,编译器,JVM,CPU都可能对用户的原始程序在保证结果一致的情况下进行重排序。
结果是: 实际运行过程中的指令的先后顺序和你程序的先后顺序不一定一致, 但是最终结果无影响。 -
原子性
原子性指的是一个操作是不可分割、不可中断的,要么全部执行并且执行的过程不会被任何因素打断,要么就全不执行。 -
可见性
可见性指的是一个线程修改了某一个共享变量的值时,其它线程能够立即知道这个修改。
volatile 和synchronized 能够保证可见性。 -
有序性
有序性指的是对于一个线程的执行代码,从前往后依次执行,单线程下可以认为程序是有序的,但是并发时有可能会发生指令重排。(实际上同一个线程的代码也不一定是顺序的,编译器和处理器都可能在as-if-serial的前提下进行指令重排)
synchronized和volatile都可以保证多线程有序性。