JMM的基本概念
Java作为平台无关性语言,JLS(Java语言规范)定义了一个统一的内存管理模型JMM(Java Memory Model)。
JMM规定了jvm内存分为主内存和工作内存 ,主内存存放程序中所有的类实例、静态数据等变量,是多个线程共享的,而工作内存存放的是该线程从主内存中拷贝过来的变量以及访问方法所取得的局部变量,是每个线程私有的其他线程不能访问。
每个线程对变量的操作都是以先从主内存将其拷贝到工作内存再对其进行操作的方式进行,多个线程之间不能直接互相传递数据通信,只能通过共享变量来进行。

从上图来看,线程1与线程2之间如要通信的话,必须要经历下面2个步骤:
首先,线程1把本地工作内存中更新过的共享变量刷新到主内存中去。
然后,线程2到主内存中去读取线程1之前已更新过的共享变量。
主内存与工作内存的数据交互
JLS一共定义了8种操作来完成主内存与线程工作内存的数据交互:
lock:把主内存变量标识为一条线程独占,此时不允许其他线程对此变量进行读写
unlock:解锁一个主内存变量
read:把一个主内存变量值读入到线程的工作内存
load:把read到变量值保存到线程工作内存中作为变量副本
use:线程执行期间,把工作内存中的变量值传给字节码执行引擎
assign:字节码执行引擎把运算结果传回工作内存,赋值给工作内存中的结果变量
store:把工作内存中的变量值传送到主内存
write:把store传送进来的变量值写入主内存的变量中
使用标准的操作再来重现一下上方的2个线程之间的交互流程则是这样的:
线程1从主内存read一个值为0的变量x到工作内存
使用load把变量x保存到工作内存作为变量副本
将变量副本x使用use传递给字节码执行引擎进行x++操作
字节码执行引擎操作完毕后使用assign将结果赋值给变量副本
使用store把变量副本传送到主内存
使用write把store传送的数据写到主内存
线程2从主内存read到x,然后load–>use–>assign–>store–>writ
另外使用这8种操作也有一些规则:
read 和 load必须以组合的方式出现,不允许一个变量从主内存读取了但工作内存不接受情况出现
store和write必须以组合的方式出现,不允许从工作内存发起了存储操作但主内存不接受的情况出现
工作内存的变量如果没有经过 assign 操作,不允许将此变量同步到主内存中
在 use 操作之前,必须经过 load 操作
在 store 操作之前,必须经过 assign 操作
unlock 操作只能作用于被 lock 操作锁定的变量
一个变量被执行了多少次 lock 操作就要执行多少次 unlock 才能解锁
一个变量只能在同一时刻被一条线程进行 lock 操作
执行 lock 操作后,工作内存的变量的值会被清空,需要重新执行 load 或 assign 操作初始化变量的值
对一个变量执行 unlock 操作之前,必须先把此变量同步回主内存中

万水千山总是情,点个 “在看” 行不行!!!
本文深入探讨Java内存模型(JMM),阐述其如何确保多线程环境下数据的一致性和可见性。JMM定义了主内存与工作内存的概念,以及线程间通过共享变量进行通信的机制。文章详细介绍了JMM规定的8种操作,这些操作规范了主内存与工作内存之间的数据交互过程。
1348

被折叠的 条评论
为什么被折叠?



