java JMM模型

基础概念(了解JMM的前提)
1、CPU,高速缓存,内存的关系

.高速缓存(Cache):高速缓存是计算机体系结构中的一级或多级缓存,用于存储CPU频繁访问的指令和数据。它位于CPU和主存储器(内存)之间,速度比主存储器更快。高速缓存的目的是提高CPU的访问速度,通过在CPU需要时提供快速访问的数据和指令,减少对主存储器的访问次数。
内存:内存是计算机系统中用于存储数据和程序的临时存储器。它用于存储当前正在执行的程序、操作系统和其他运行时数据。内存通常是以字节为单位进行寻址和访问的,它提供了更快的数据访问速度,相对于较慢的存储系统(如磁盘)。
2、JMM内存模型(JMM存在必要性参考CPU高速缓存和内存的关系)
Java内存模型(Java Memory Model简称JMM)是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。
图示:
在这里插入图片描述
主内存
主要存储的是Java实例对象,所有线程创建的 实例对象都存放在主存中,不管该实例对象时成员边浪还是方法中的本地变量,当然还包含共享的类信息、常量、静态 变量。由于是共享数据区域,多条线程对同一个变量进行访问可能会发生线程安全问题。

工作内存
主要存储当前方法的所有本地变量(工作内存中存储着主内存中的变量副本拷贝),每个线程只能访问自己的工作内存,即线程中的本地变量对其他线程是不可见的,就算是两个线程执行的是同一段代码,它们也会各自在自己的工作内存中创建属于当前线程的本地变量,当然也包括了字节码行号指示器、相关Native方法的信息。
由于工作内存是每个线程的私有数据,线程间无法相互访问工作内存,因此存储在工作内存的数据不存在线程安全问题。
根据JVM 虚拟机规范主内存与工作内存的数据存储类型以及操作方式,对于一个实例对象中的成员方法而言,如果方法中包含本地变量是基本类型,将直接存储在工作内存的栈帧结构中,但倘若本地变量是引用类型,那么该变量的引用会存储在工作内存的栈帧中,而对象实例将存储在主内存(共享内存区域,堆中)。
但对于实例对象的成员变量,不管它是基本数据类型或者包装类型还是引用类型,都会存储在堆中。
至于static变量以及类本身相关信息将会存储在主内存中。
在主内存中的实例对象可以被多线程共享,倘若两个线程同时调用了同一对象的同一方法,那么两条线程会将要操作的数据拷贝一份到自己的工作内存中,执行完成操作后才刷新到主内存中。
Java内存模型与硬件内存架构的关系
对于硬件内存来说只有寄存器、缓存内存、主内存的概念,并没有工作内存之分,也就是说Java内存模型对内存的划分对硬件内存并没有任何影响,因为JMM只是一种抽象的概念,是一组规则,并不实际存在,不管是工作内存的数据还是主 内存的数据,对于计算机硬件来说都会存储在计算机主内存中,当然也有可能存储在到CPU缓存或者寄存器中

因此总体上来 说,Java内存模型和计算机硬件内存架构是一个相互交叉的关系,是一种抽象概念划分与真实物理硬件的交互。
在这里插入图片描述volatile关键字的作用
保持多个线程对共享数据操作内存的可见性
禁止指令重排序

例子:
对于一个静态变量
static int s = 0;
线程A执行如下代码:
s = 3;
线程B打印s
会出现两种情况
1: 工作内存所更新的变量同步到主内存,才被B线程打印,从而输出s=3.
2 :因为工作内存所更新的变量并不会立即同步到主内存,所以虽然线程A在工作内存当中已经把变量s的值更新成3,但是线程B从主内存得到的变量s的值仍然是0,从而输出 s=0。
synchronized属于重量级锁,虽然可以解决此问题,但是对性能不友好。
什么时候使用volatile关键字
1.运行结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
2.变量不需要与其他的状态变量共同参与不变约束。
第一条很好理解,。第二条是什么意思呢?可以看看下面这个场景:

volatile static int start = 3;
volatile static int end = 6;
线程A执行如下代码:
while (start < end){
//do something
}
线程B执行如下代码:
start+=3;
end+=3;
这种情况下,一旦在线程A的循环中执行了线程B,start有可能先更新成6,造成了一瞬间 start == end,从而跳出while循环的可能性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值