什么是java内存模型?理解java内存模型的用处?

概念

java内存模型 (JMM,java Memory Model).JMM规定了java线程如何以及何时能够看到其他线程修改过的共享变量的值,以及在必须时如何同步的访问共享变量.

JMM结构

jmm结构图

在jmm模型中,对象的引用和局部变量是存储在虚拟机栈上的,如果线程想要访问堆上的对象,线程会将堆中的对象加载到线程栈中,持有对象的私有拷贝.

多线程操作共享变量出现非预期结果的的本质就是线程对本地线程栈中共享变量的副本进行操作,操作完成之后会把共享变量的副本同步到主内存中, 可能覆盖掉之前线程操作之后同步到主内存的数据.理解了jmm模型就能更清楚的理解并发编程中常见的问题.

线程间通讯

线程之间进行通信的常见方式有两种:1.基于内存进行通讯2.基于管道进行通讯.java语言采用的是前者.像golang语言采用的是后者. 基于内存进行安全的通讯是需要建立一定的规范之上的.这个规范限制线程同步的访问共享内存保证共享数据的正确性和可见性.

jmm同步操作

jmm同步操作图解

jmm模型中线程同步的八种操作:

  1. lock(锁定): 作用在主内存的变量,将一个变量标识为一条线程独占的状态
  2. unlock(解锁): 作用在主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
  3. read(读取): 作用在主内存的变量,把一个变量值从主内存传入到线程的工作内存,以便随后的load动作使用
  4. load(载入): 作在于工作内存中的变量,他把read操作从主内存中得到的变量值放入工作内存的变量副本中
  5. use(使用): 作用在工作内存的变量,把工作内存中的一个变量值传递给执行引擎
  6. assign(赋值): 作用于工作内存的变量,把一个从执行引擎接收到的值赋值给工作内存的变量
  7. store(存储): 作用于工作内存的变量,把一个工作内存中的一个变量的值传送到主内存中,以便随后的write操作
  8. write(写入): 作用于主内存的变量,它把store操作从工作内存中一个变量的值传送到内存的变量中

jmm模型中同步操作的约束

  1. 必须先进行read才能进行load操作,这之间不一定是连续的.必须先进行store再进行write,这之间也不一定是连续的
  2. 不允许线程丢弃掉最近的assign操作.执行引擎不能放弃将修改操作后的内容写回工作内存.
  3. 不允许线程无原因的没有assign操作的时候把线程的修改同步到主内存,也就是说一个新的变量只允许在主内存中诞生, 不允许创建一个没有经过read load use assign的对象.
  4. 一个变量只允许同一时间一个线程对其进行lock操作,但是lock可以被同一条线程多次执行,多次执行lock后只有执行相同次数的unlock才能解锁.
  5. 一个变量被线程进行了lock操作,那么这个线程会清空此工作内存中此变量的值.在执行引擎需要这个值的时候重新进行load操作.
  6. 如果一个变量没有被此线程进行lock,那么也不能被这个线程unlock.执行unlock之前必须执行store write操作把变量同步到主内存中.

按照如上jmm操作和规则.多线程同步操作共享变量的大致步骤如下图: java多线程同步操作共享变量

总结

对于知识的理解,不只是理解知识点本身.而是要学习其优秀的设计思想,当在工作中遇到实际的场景的时候与所学的思想进行匹配将技术或设计思想运用在实际场景. 这时候才产生了更多的价值.