JVM学习六 java内存模型与线程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Jon_jing/article/details/94450987

一内存间交互操作

1.定义 : 关于主内存和工作内存之间具体的交互协议,即一个变量如何从主内存拷贝到工作内存,如何从工作内存同步到主内存之类的实现细节

2. 8种操作:

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

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

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

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

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

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

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

wirte(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入到主内存变量中

变量从主内存复制到工作内存:read和load

变量从工作内存同步到主内存:store和write

注意:java内存模型只要求上述两个操作必须按照顺序执行,但是没有保证是连续执行

3.执行8种基本操作时必须满足如下规则:

 不允许read和load,store和write操作之一单独出现,即不允许一个变量从主内存读了之后但工作内存㝂,或者从工作内存发起回写了但是主内存不接受的情况出现

不允许一个线程丢弃它最近的assign操作,即变量在工作内存中改变了之后就必须把该变化同步回主内存

不允许一个线程无原因地(没有发生过任何assign操作)把数据从线程的工作内存同步回主内存中

一个新的变量只能在主内存中“诞生”。不允许在工作内存中直接使用一个未被初始化(load或assign)的变量,换句话说,就是对一个变量实施use,store操作之前必须先执行过了assign和load操作

一个变量在同一时刻只允许一条线程对其执行lock操作,但是lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁

如果一个变量执行lock操作锁定,那将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值

如果一个变量实现没有被lock操作锁定,那就不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定住的变量

对一个变量执行unlock操作之前,必须先把此变量同步回主内存(执行store,write操作)

二 对于volatile型变量的特殊规则

1. volatile 变量只能保证可见性

2.在不符合一下两条规则的运算场景中,我们仍要加锁保障原子性

运算结果并不依赖变量的当前值,或者能够保证只有单一的线程修改变量的值

变量不需要与其他的状态变量共同参与不变约束

三 原子性,可见性和有序性

1.原子性:基本数据类型的访问读写都具有原子性,synchronized关键则之间的操作也具备原子性

2.可见性:是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改,volatile,final,synchronized都可以实现可见性

3.有序性:如果在本线程内观察,所有的操作都是有序的,如果在一个线程中观察另一个线程,,所有操作都是无序的。

volatile和synchronized两个关键字来保证线程之间的有序性

四 先行发生原则

1. 定义:是用来判断数据是否存在竞争,线程是否安全的主要依据。

2:先行发生就是java内存模型中定义的两项操作之间的偏序关系,如果说操作A先行发生于操作B,其实就是在说发生操作B之前,操作A产生的影响能被操作B观察到,影响包括了,修改内存中共享变量的值,发送了消息,调用了方法等

五 java与线程

1.线程的实现:三种方式

使用内核线程实现:直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器对线程进行调度,并负责将线程的任务映射到各个处理器上,每个内核线程可以视为内核的一个分身,这样操作系统就有能力同时处理多件事情,支持多线程的内核叫做多线程内核 

使用用户线程实现:一个线程只要不是内核线程,就可以认为是用户线程。所有的线程操作都需要用户程序自己处理,线程的创建,切换和调度都需要考虑

使用用户线程加轻量级进程混合实现:

2.线程调度:是为线程分配处理器使用权的过程

调度方式有两种:分别是协同是线程调度和抢占式线程调度

猜你喜欢

转载自blog.csdn.net/Jon_jing/article/details/94450987