java虚拟机(七)--java内存模型JMM

  本文参考慕课网相关视频和博客https://mp.weixin.qq.com/s/tV0MfDdJqGwGMHCIkqnAgA,图也是这个博客的,这篇只是自己的简单总结,想要入理解可以访问这两块内容。

一、内存模型定义

  java memory model(简称JMM),这是一个抽象的概念,不是真实存在的。它是一种规范,利用这些规范,更方便的开发多线程程序。如果没有JMM,Java代码运行在不同的虚拟机上面结果可能会发生不一致。了解java内存模型之前,需要先了解下面的内容。

二、CPU多级缓存

  随着CPU的发展,其频率太快了,主存无法跟上,这样导致CPU需要等待主存,大大浪费资源。所以为了解决CPU和主存之间速度不匹配的情况,在二者之间出现了缓存。CPU能力不断提升,一层缓存往往无法满足要求,逐渐衍生出多级缓存。CPU缓存可以分为一级缓存(L1),二级缓存(L2),部分高端CPU还具有三级缓存(L3),每一级缓存中所储存的全部数据都是下一级缓存的一部分,L1,L2,L3缓存数据大小逐渐变少,而其处理速度也是逐渐变小的。

   单核CPU只含有一套L1,L2,L3缓存。

  多核CPU,则每个核心都含有一套L1(甚至和L2)缓存,而共享L3(或者和L2)缓存。

三、缓存一致性问题MESI:可见性问题

  在CPU和主存之间增加缓存,在多线程场景下就可能存在缓存一致性问题,也就是说,在多核CPU中,每个核的自己的缓存中,关于同一个数据的缓存内容可能不一致。缓存一致性协议保证多个CPU cache之间缓存共享数据的一致性。

四、乱序执行优化(原子性)、指令重排(有序性)

  CPU为了提高处理速度对代码执行顺序做出改变顺序的优化。

  很多编程语言的编译器也会有类似的优化,比如Java虚拟机的即时编译器(JIT)也会做指令重排。

五、java内存模型:Java Memory Model简称JMM

  它是一种规范,规定了jvm和计算机内存如何协同工作的,一个线程如何和何时得到别的线程修改过后的共享变量的值,如何同步的访问共享变量。JMM是很多工具类和关键字的原理,例如Lock、Synchronized、volatile等

  所有的变量都存储在主内存中,每条线程还有自己的工作内存(不是真实存在的),保存了该线程中是用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写内存。不会有线程安全的问题。不同的线程之间也无法直接访问对方工作内存中的变,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。

主内存:

  Java 内存模型规定了所有变量都存储在主内存(Main Memory)中(此处的主内存与介绍物理硬件的主内存名字一样,两者可以互相类比,但此处仅是虚拟机内存的一部分)。

工作内存:

  每条线程都有自己的工作内存(Working Memory,又称本地内存,可与前面介绍的处理器高速缓存类比),线程的工作内存中保存了该线程使用到的变量的主内存中的共享变量的副本拷贝。

JMM抽象示意图如下:

两个线程中去通信一定要经过主存

步骤:

  线程A要将本地内存A操作过后的共享变量刷新到主存中,线程B到主存中去读取更新过后的共享变量。

通过下面的操作来保证同步:

  lock、unlock、read、load、use、assign、store、write

   所以我们需要通过某些措施保证同步,线程同步需要满足:原子性、可见性、有序性,或者说是JMM的三大特性:重排序,可见性,原子性。相关代码演示和解决方案,请具体内容参考:并发和多线程(七)--线程安全、synchronized、CAS简介

原文地址:https://www.cnblogs.com/huigelaile/p/10840601.html