Java内存模型与线程(一)

时间记录:2019-1-23
此标题内容为学习java虚拟机做的笔记和小总结汇总。

java内存模型

我们知道java为了实现跨平台(指的是相同的代码在不同的平台的java环境下可以正常运行),专门的对物理机的内存进行分配了规则,比我我们常说的,主内存,工作内存等,为的是可以消磨在不同的环境下的差异性,约定内存的数据访问的规则等。

主内存与工作内存

我们了解java定义的内存模型主要是定义程序中各个的变量的访问规则,即是在将虚拟机的内存如何放到物理机内存和从物理机内存中拿到虚拟机中。
这里的交互数据,主要为变量,但是这里的变量不是说我们平常定义的一个变量,而是指实例字段,静态字段和构成数组对象的元素,但是不包括局部变量和方法参数,主要是和物理机的内存进行交互的(这里指的是虚拟机占用外的物理机内存)

内存会分成主内存和工作内存两种
主内存:主内存可以认为是物理机的内存但是仅表示虚拟机占用的部分。
1:所有的变量都存储在主内存中
工作内存:指的是每一个线程使用的内存,可以与cpu的高速缓存对比,指的是我们通常所说的一级缓存和二级缓存,三级缓存的(除少部分机器不存在三级缓存)
1:工作线程保存了该线程使用的所有的变量也就是从主内存中拷贝的副本
2:线程对所有的变量的操作,都是在工作内存中的,不能直接读取主内存的变量
3:不同线程中的变量不能直接访问,也就是不能访问对方的直接内存。
4:线程直接的变量只能通过主内存进行交互

注意:

我们在多线程的编程中常用到锁这个东西,原因就是在这里,线程使用的是工作内存中的数据,然后不是使用的主内存中的数据,而线程使用的数据是主内存数据中的拷贝副本,但是主内存的数据和工作内存数据的同步刷新是需要时间的,然后就造成了多线程的数据不一致问题,也就是需要锁的原因。

上面说的拷贝的副本不是拷贝所有的内容,是拷贝当前需要使用的内容,不然cpu的内存还不撑爆了

基本上的如下图的内存

java线程 <=> 工作内存 <=> 主内存

这里的工作内存是指的cpu的缓存,主内存就是指物理机的内存,而java虚拟机就是对这些内容进行整理和划定规则的。

内存间交互操作

内存间的交互操作,主要是指将内存从主内存拷贝到工作内存和从工作内存拷贝到主内存中,在java虚拟机中定义了8中操作,且其中的所有操作都是原子操作,而且某些的操作存在一定的顺序性和规则性,但是某些特殊的内容在一些平台上允许例外
主内存操作 lock unlock read write 工作内存操作 load use assign store
以上为在主内存和工作内存中的操作
lock(锁定): 这个就是我们常说的锁操作,将一个变量锁定给到一条独立的线程使用,而且不能给其它的线程操作,只有在当前的线程释放的时候才能给其它的线程操作。之前我们说过的线程拷贝的变量的副本,这里锁定后,即其它线程不能进行拷贝副本,完全是有主内存控制的。
unlock(解锁): 和锁定是相对应的,指的是将变量释放,给予其它的线程进行拷贝操作。
read(读取): 是用于工作线程进行拷贝副本使用的,即将变量从主内存传输到工作内存中,以供工作内存进行一些操作。
wirte(写入): 和读取相对的是将工作内存中的store的变量的值放到主内存中,即是指变量的同步操作。

load(载入): 主内存中进行读取的变量,也就是拷贝到的副本加载到工作内存中,进行使用。
use(使用): 工作内存进行使用,主要说为字节的指令使用这个可以去了解下帧的注入操作,即将变量的值入帧。
assign(赋值): 进行字节指令操作的结果赋值到当前工作内存的变量上
store(存储): 存储就是指将工作内存中的值,传入到主内存中,然后有主内存进行操作保存。

一个变量的整个操作流程如下:
read => load => use => assign => store => write
当然在read和load ,store和write中间可以插入一些其他操作。

当然其中存在一些规则
1:read和load,store和write操作不能单一出现,即主内存和工作内存都必须接受这样的操作,不能不接受,也就是说主内存给工作内存数据是工作内存不能不接受,和工作内存给主内存数据时主内存不能不接受
2:工作线程一旦进行了assign的操作就必须得同步和主内存,即在工作内存中变量的值发生了变化的时候,必须要进行同步操作。
3:同第二点相似,变量必须在发生变化的时候才能够同步会主内存,其余不予许随意进行同步操作
4:变量只能够在主内存中进行创造,不能够在工作内存中进行创造,也就是工作内存只能使用已经被初始化的变量
5:一个变量只能对一个线程lock操作,但是一个变量可以被同一个线程多次的lock。这个和重入锁相似。
6:在lock一个变量的时候,首先得将变量的值获取到最新的,如果线程中已经存在了那么会先清空变量的值,然后重新load
7:没有内lock的变量是不能unlock的,这点和锁类似
8:unlock的时候必须要将变量同步回到主内存,这样是为了保证变量数据的最新,保证了在多线程中的数据一致性
时间记录:2020-1-31

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值