当前位置:网站首页>JMM 内存模型概念
JMM 内存模型概念
2022-07-29 05:27:00 【魔道不误砍柴功】
JMM 内存模型概念
我们知道 CPU 直接操作高速缓存寄存器,而不是直接操作主内存,那么有缓存的话,就会造成数据一致性问题,所以为了解决这些问题,提出了 JMM 规范。
JMM 全称为 Java Memory Model,Java 虚拟机定义出一种逻辑规范或者说是抽象概念,用来屏蔽各种硬件和操作系统内存的访问差异,实现让 Java 程序在各种平台下都能达到一致的内存访问效果。换句话说就是通过这组规范定义了程序中对共享变量的读写能够互相可见,尤其是多线程情况下的读写操作,都是围绕着多线程的原子性、可见性、有序性展开的。
对JMM 还应该要有认识的点,如下:
不用 Java 虚拟机的内存区域划分,是两种逻辑的存在,是不同层次的划分结果,侧重点各有不同。
主内存可以对应 Java 中的堆内存,工作内存可以对应栈中的部分。
更底层次地来说,主内存对应硬件的物理内存,工作内存对应的是寄存器和高速缓存寄存器。
JMM 操作内存示意图

从图中发现线程操作共享变量,都需把主内存中共享变量拷贝一份到自己的工作内存中,然后才可以进行操作,操作完之后又在写回主内存。如果考虑到高并发场景下,各个线程先把值在自己的工作内存中修改过后,假设有个线程先把值赋值回去了,此时主内存的值已经修改了,但是另一个线程还是拿着自己工作内存中的数据在操作,然后又给写回去了,明显这里第二个线程写回去的数据是有问题的,那么这里我们怎么可以保证,让一个线程修改主内存中的值,然后通知到其他线程,这里就涉及到了线程的可见性问题了,也是 JMM 三大特性之一,在了解线程可见性之前我们先看下 JMM 给我提供的8种原子操作来辅助各线程间内存间的交互?
JMM 8个原子操作(内存间的交互操作)
这八个原子操作类也是实现了线程可见性的基础步骤,如下:
lock: 锁定,把变量标识为线程独占,作用于主内存变量unlock:解锁,把锁定的变量释放,其他线程才能使用,作用于主内存read:读取,把变量值从主内存中读取到工作内存(只是读取到了工作内存,并没有指定到某个变量)load:载入,把 read 读取到的变量放入工作内存中的副本变量中use:使用,把工作内存中一个变量的值传递到执行引擎assign:赋值,把从执行引擎接受到的值赋值到工作内存中的副本变量中store:存储,把工作内存中的变量传递到主内存中(只是存储到了主内存,并没有指定到某个变量)write:写入,把 store 存储进来的值写入到主内存中的共享变量
下图展示了两个线程同时对主内存中的共享变量 flag 修改过程:
首先线程要从主内存中读取共享变量的值,那么首先就要给这个共享变量加锁(lock 操作),然后通过 read 操作,把 flag 的值从主内存读取到工作内存中(其实就是高速缓冲寄存器),然后再通过 load 操作,将工作内存中 flag 的值加载到变量副本中,然后通过 use 操作,将变量的值传递给 CPU 执行引擎。
CPU 执行完之后,通过 assign 操作,将计算结果存储到变量副本中,接着通过 store 操作,将变量副本的 flag 值从工作内存传递给主内存,然后执行 write 操作,把 flag 的值重写写会到主内存中的共享变量 flag,最后通过 unlock 操作线程释放该锁,其他线程又可以对此变量加锁,重复上述流程。
然后这里有几个内存间交互的规则需要注意下:
- 不允许 read 和 load、store 和 write 操作单独出现,以上两个操作必须按照顺序执行,但不保证连续性,也就是说 read 和 load、store 和 write 之间是可以插入其他指令的
- 不允许一个线程丢弃它最近的 assign 操作,即变量在工作内存中改变了之后必须把该变化同步会主内存
- 不允许一个线程无原因的(没有任何的 assign 修改赋值操作)把数据从工作内存同步会主内存中年
- 一个新的变量只能从主内存中诞生,不允许在工作内存中直接使用一个未初始化的变量,也就是对一个变量实施 user 和 store 操作之前,必须先执行过了 load 和 assign 操作
- 一个变量在同一时刻只允许一个线程对其 lock 操作,但 lock 操作可以被同一个线程多次重复执行,多次 lock 后,只有执行相同次数的 unlock 操作,变量才会解锁
- 如果对一个变量执行 lock 操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新 load
- 如果一个变量没有被 lock 锁定,则不允许对它执行 unlock 操作,也不能 unlock 一个被其他线程锁定的变量
- 对一个变量执行 unlock 之前,必须先把此变量同步会主内存(执行 store 和 write 操作)
边栏推荐
- 一文看懂网络安全五年之巨变
- 如何在开发板上使用sftp命令访问sftp-server
- FPGA - odd even frequency division and decimal frequency division code routine
- day03_2_作业
- Sequence list and linked list
- Several misunderstandings about DDoS
- Phishing mail disposal
- 什么是DNS放大攻击
- Merkletree builds QT implementation UI
- IGMP protocol software development experiment
猜你喜欢

day04_数组

LDAP简述及统一认证说明

OpenResty的核心与cosocket

day15_ generic paradigm

day13_多线程下

Complex floating point division of vivado IP core floating point

5、 Wireless communication network

C语言内存-栈与堆使用

day02_ Basic grammar
![[interview questions] the latest software test interview questions in 2022 (400) [with answers] continue to update](/img/72/445d78bdd6c921cc5a0843f056c435.png)
[interview questions] the latest software test interview questions in 2022 (400) [with answers] continue to update
随机推荐
Phishing mail disposal
'function vtable for error: undefined reference to ... ' 问题的原因及解决方法
MQTT服务器搭建以及使用MQTT.fx测试
2022年的软件测试的岗位要求为何越来越高?这其中有什么不可告人的秘密吗?
Hongke share | FPGA implementation of pass through and store and forward switching delay
Hongke | uses jesd204 serial interface to bridge analog and digital worlds at high speed
IPv6 representation and configuration cases
day10_ Exception handling & enumeration
Hongke automation SoftPLC | Hongke kPa modk operation environment and construction steps (2) -- modk operation environment construction
关于DDoS的几个误区
3、 Wide area communication network
day12_ Multithreading
day14_ Unit test & Date common class & String common class
超低成本DDoS攻击来袭,看WAF如何绝地防护
Hongke shares | why EtherCAT is the best solution to improve the performance of the control system?
Solution for website being suspended
LDAP简述及统一认证说明
5、 Wireless communication network
FPGA—奇偶数分频和小数分频代码例程
day04_数组