JDK并发集合2:JMM模型(基础篇)

上一篇讲到CPU提供了两个接口让用户可以自己刷新Store buffer和失效队列,这一篇我们来看下为了更好的理解如何实现同步的可见性,JMM抽象出来的内存屏障Memory Barrier。

JMM内存模型

java作为一个跨平台的语言,需要面对不同的底层硬件系统,它设计一个中间层模型来屏蔽底层的硬件差异,给上层的开发者一个一致的使用接口。JMM模型就是这样一个中间层的模型。

JMM内存模型定义:

Java内存模型(Java Memory Model,JMM)是在硬件内存模型基础上更高层的抽象,它屏蔽了各种硬件和操作系统对内存访问的差异性,从而实现让Java程序在各种平台下都能达到一致的并发效果。

Java内存模型定义了程序中各个变量的访问规则,即在虚拟机中如何将变量存储到内存和从内存中取出这样的底层细节。这里所说的变量包括实例字段、静态字段,但不包括局部变量和方法参数,因为它们是线程私有的,它们不会被共享,自然不存在竞争问题。它的基本原则是:

  • 理论上所有stack和heap都存储在物理内存,但随着CPU运算其数据副本可能被缓存或寄存器持有,遵从一致性协议
  • 多个线程访问同一对象时,每个线程拥有该对象成员变量的私有拷贝

为了解决不同线程间变量可见性以及如何同步共享变量的问题,JMM抽象出了内存屏障Memory Barrier。它定义了同步的八个操作,以及使用这八个操作需要遵守的规则。

  • lock:主内存中的变量被线程独占
  • unlock:将主内存中被锁定的变量释放出来
  • read:变量的值从主内存传输到工作内存
  • load:把read得到的变量的值放到工作内存的副本中
  • use:把工作内存中变量的值传给执行引擎
  • assign:在工作内存中存储从执行引擎传过来的值
  • store:把工作内存的值传输到主内存
  • write:把store操作获取的值放入到主内存的变量中

1195582-20180508173343513-2029065762

其同步的八个操作的操作规则:

  • 不允许read和load,store和write操作之一单独出现
  • 不允许线程丢弃其assign操作
  • 不允许没有assign就把数据从工作内存同步回主内存
  • 变量只能在主内存“诞生”(即对一个变量实施use和store操作之前,必须先执行过了assign和load操作。 )
  • 一个变量在同一个时刻只允许一条线程对其进行lock操作
  • lock操作会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值。
  • 如果事先没有被lock操作锁定,则不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定住的变量。

refer:https://www.cnblogs.com/yanlong300/p/8986041.html
https://www.cnblogs.com/yanlong300/archive/2004/01/13/9009687.html

comments powered by Disqus