Java内存模型、内存间的交互操作、JVM运行时数据区以及和堆栈之间的关系

1、讲Java内存之间的交互操作之前,首先得说一下Java的内存模型

因为Java的内存模型定义了在虚拟机中将变量存储到内存和从内存中取出变量的底层细节,它的主要目标是定义程序中各个变量的访问规则,所以得先聊一聊Java内存模型

一提Java的内存大家应该会想到,那不就是平常说的堆、栈、方法区这些吗?

其实并不是的,如上图所示,平常说的堆、栈、方法区这些应该称之为JVM运行时数据区,而不是Java内存模型

Java内存模型将内存分为了主内存和工作内存
Java内存模型规定所有的变量都存储在主内存中,每个线程有自己的工作内存
主内存主要包括:堆和方法区,主内存是所有线程共享的
工作内存主要包括:该线程私有的栈和对主内存部分变量拷贝的寄存器(包括程序计数器和cpu高速缓存区)

2、Java内存模型规定了所有变量都存储在主内存中,每个线程有自己的工作内存,线程对变量的所有操作都必须在自己的工作内存中进行,而不能直接读写主内存中的变量,不同线程之间也无法直接操作对方工作内存中的变量,线程间变量值的传递需要通过主内存来完成,Java内存模型是围绕着在并发过程中如何处理原子性、可见性和有序性来建立的

3、JVM规范定义了线程对内存间交互的八种操作:

lock(锁定):作用于主内存的变量,它把一个变量标识为一个线程独占的状态

unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定

read(读取):作用于主内存的变量,它把一个变量的值从主内存传送到线程中的工作内存,以便随后的load动作使用

load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中

use(使用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎

assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存中的变量

store(存储):作用于工作内存的变量,它把工作内存中的一个变量的值传送到主内存中,以便随后的write操作

write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值写入主内存的变量中
虚拟机必须保证以上的每一种操作都是原子的

在将变量从主内存读取到工作内存中,必须顺序执行read、load

要将变量从工作内存同步回主内存中,必须顺序执行store、write

以上八种操作必须遵循以下八条规则:

(1):不允许read和load、store和write操作之一单独出现。即不允许一个变量从主内存被读取了,但是工作内存不接受,或者从工作内存回写了但是主内存不接受。

(2):不允许一个线程丢弃它最近的一个assign操作,即变量在工作内存被更改后必须同步改更改回主内存。 

(3):工作内存中的变量在没有执行过assign操作时,不允许无意义的同步回主内存。 

(4):在执行use前必须已执行load,在执行store前必须已执行assign。 

(5):一个变量在同一时刻只允许一个线程对其执行lock操作,一个线程可以对同一个变量执行多次lock,但必须执行相同次数的unlock操作才可解锁。

(6):一个线程在lock一个变量的时候,将会清空工作内存中的此变量的值,执行引擎在use前必须重新read和load。

(7):线程不允许unlock其他线程的lock操作。并且unlock操作必须是在本线程的lock操作之后。

(8):在执行unlock之前,必须首先执行了store和write操作。

发布了108 篇原创文章 · 获赞 103 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/ju_362204801/article/details/87884019