深入理解java虚拟机:java内存模型与线程

下图是并发产生不一致性问题的基本原因:

 还有指令重排优化,

1、java内存模型

java虚拟机试图定义一组java内存模型规范,来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能到达一致的内存访问结果。java内存模型的主要目标是定义程序的各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出来这样的细节。java内存模型规定了所有变量存储于主内存,每条线程还有自己的工作内存,存储该线程使用的变量的拷贝副本,线程对所有变量的使用都必须在工作内存中进行,不能直接访问主内存。不同线程不能相互访问工作内存,线程间的变量值传递均通过主内存完成。线程,主内存,工作内存之间的关系如下图:

为了获取更高的速度,会让工作内存优先存储于寄存器或者告诉缓存,程序运行主要访问工作内存。虚拟机使用一个对象的拷贝,只会拷贝引用和线程用到的变量不会拷贝整个对象。堆数据除了存储对象其他信息,对于hotspot虚拟机还存储了markword(存储对象哈希码,GC标志,GC年龄,同步锁等信息)klass point(指向存储类型元数据的指针)

 2、内存间交互操作

对于主内存和工作内存的交互协议,一个变量如何从主内存复制到工作内存,又如何从工作内存同步回主内存的操作细节,java内存模型定义如下8个操作,这八个操作都是原子的不可分的。

扫描二维码关注公众号,回复: 8062392 查看本文章

1)lock 作用于主内存变量,将变量标识成一条线程占用

2)unlock作用于主内存变量,将锁定变量释放。

3)read作用于主内存变量,将一个变量读取到工作内存,以便后续load操作。

4)load作用于工作内存变量,将一个变量读取到工作内存副本中

5)use作用于工作内存变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时就会执行这个操作。

6)assign作用于工作内存变量,将工作引擎接收到的值赋给工作内存变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。

7)store作用于工作内存将一个变量值传输到主内存以便后面的write操作可以使用。

8)write作用于主内存的变量,他把store从工作内存得到的变量放入到主内存的变量中

read,load,store write必须顺序并且成对出现。不允许丢弃它的最近的assign操作,即变量在工作内存中改变的变量值必须同步到主内存。不允许一个线程没有发生assign操作就把工作内存同步到主内存。

一个新变量只能在主内存中产生,不允许在内存中直接使用未被初始化操作的变量(load和assign)就是use,store之前必须load和assign。一个变量只能被一个线程lock,同一个线程可以多次执行lock操作,

多次lock后必须相同次数unlock才能解锁。如果对一个变量执行lock后,会清空他的工作内存此变量的值,也就是执行引擎使用这个值之前必须要load或assing操作。对一个变量执行unlock时必须将工作内存同步到主内存中如store,write

猜你喜欢

转载自www.cnblogs.com/xiaofeiyang/p/11979035.html
今日推荐