1.概述
JMM,JAVA多线程内存模型,JAVA中有两个内存模型,一个是JVM——JAVA虚拟机内存模型,一个是JMM——JAVA多线程内存模型,两者不是一个概念,需要严格区分。JMM的逻辑架构如下:
JMM主要是由两部分组成一部分是主存、一部分是工作内存。主存,即JVM的堆空间,工作内存,即CPU中的寄存器。JMM中的工作内存是个抽象概念,其本质是基于CPU的寄存器实现的,多条线程复用一个CPU,各自在寄存器中的数据独立。CPU的处理速度和主存的读写速度量级差距巨大,如果每次CPU中的线程都与主存进行数据交互,对于CPU的资源过于浪费,因此在架构上加上了一级缓存用来适配速度差,缓存还是不够快,于是又加上了一级寄存器。(如果不是很清楚的读者,可以去学习一下计算机组成原理,存储相关的内容)每个CPU都有一个自己的寄存器,这个寄存器便是每个线程的工作内存,寄存器中存放的是当前CPU即将要执行的线程所需要的数据,这些数据自工作内存中加载,可以理解为主内存中的一个副本,之后的读写操作均使用位于工作内存的变量副本,并在某个时刻将工作内存的变量副本写回到主存中去。
因为JMM底层机制的原因,工作内存中的数据是副本,所以以下程序会陷入死循环
这类由于多线程环境中出现的一些问题,叫做线程安全问题,如何解决线程安全问题,是JAVA多线程中的一个重点内容,后面会详细介绍 。
2.八大原子操作
原子操作,即无法再进行分割的最小操作,在此操作执行过程中不会被“第三者插足”。针对数据在主存与本地内存间的流转,JMM有8大原子操作:
1.read,读取,从主存中读取数据
2.load,载入,将主存中数据写入工作内存
3.use,使用,从工作内存中读取数据来计算
4.assign,赋值,将计算好的值重新赋值到工作内存中
5.store,存储,将工作内存数据写入主存
6.write,写入,将store过去的变量赋值给主存中的变量。
7.lock,加锁,将主存中的变量加锁,标识为线程独占状态。
8.unlock,解锁,将主存中的变量解锁,解锁后其他线程可以锁定该变量。
以上面程序为例,整个运行过程中的原子操作流程如下: