java内存模型验证_JVM Java内存模型

内存间相互交互

工作内存与主内存之间有规定的协议.即一个变量如何从主内存拷贝到工作内存中,又如何从工作内存同步变量到主内存中.以下有8个操作指令:

1.lock(锁定)作用于主内存的变量中,锁定并让某线程独享

2.unlock(解锁)作用于主内存的变量中,解锁变量以让其他线程访问

3.read(读取)作用于主内存变量中,以便工作内存下一步的load操作

4.load(载入)作用于工作内存中,载入从主内存中读取的变量

5.use(使用)作用于工作内存中.他把工作内存中的值传递给执行引擎,每当虚拟机需要使用到变量值的时执行这个操作

6.assign(赋值)作用于工作内存中,他把从执行引擎中返回的最新值赋值给变量,每当虚拟机遇到一个给变量赋值的字节指令码时执行这个操作

7.store(存储)作用于工作内存中,它把工作内存中的值传递到主内存中,以便下一步的write操作

8..write(写入)作用于主内存中,它把从store操作获取的值更新到内存中

上述的8中基本操作必须满足以下规则:

1.不允许read、load和store、write单独出现

2.不允许线程对其最近的assign操作,即工作内存中的变量改变后必须同步到主内存中

3.不允许一个线程无原因的同步变量到主内存中

4.一个新的变量只能从主内存中产生.工作内存中不允许使用未被初始化(load、assign)的变量

5.变量最多只能同时被一个线程执行load操作,且可以操作任意次,相对的需要执行一样多次的unlock操作.

6.lock操作时会清除工作内存中的变量的值.当需要读取时再从主内存中载入

7.如果一个变量没有进行lock操作那就不允许执行unlock操作,也不能去unlock其他线程锁定的变量

8.在执行unlock操作前变量必须先同步到主内存中

Volatile变量的特殊性

关键字volatile可以说是Java虚拟机最轻量级的同步机制

一个变量被定义为volatile,它将具备两种特性:

1.保证变量对所有线程的“可见性”变量的改变将会同步更新到其他的拥用该变量的线程中,而普通的变量不能做到这里点,普通变量的值在线程间传递均需要通过主内存来完成,需要注意的是:volatile只能保证变量的可见性,在多线程的环境中也并非是绝对安全的

2.使用volatile变量表示禁止指令重排序优化

线程安全指标:可见性、原子性、有序性

Java内存模型是围绕着可见性、原子性、有序性这三个特征建立的

1.原子性(Atomicity):

由Java内存模型来保证原子性的操作有read、load、assign、use、store、write, 大致可以认为基本数据类型的访问读写是具备原子性。如果需要一个更大的原子性保证,还有lock和unlock,在虚拟机中没有直接把这两操作给用户使用,而是隐式的在字节                           码添加指令monitorenter和monitorenter进行操作.这两个字节码对象jdk代码中就是同步块-synchronize关键字

2.可见性(Visibility):

可见性是指当线程改变了共享的变量,其他线程能够马上知道此次的修改

2.1:volatile就验证了这一点

2.2:synchronize也是可见性的,因为在其unlock操作之前,必须把变量值同步到主内存中

2.3 final也是有可见行.因为被final修饰的字段一旦被构造器初始化完成,并且构造器没把this传递出去,那在其他线程中就能看见final字段的值(WTF?不懂)

3.有序性(Ordering):

编译器或者运行时环境为了优化程序性能,会对代码进行重排序.而volatile关键字本身就禁止指令重排序,synchronize则是由“一个变量在同一时刻只能有一个线程进行lock操作”获得.持有同一个锁的两个同步块只能串行的进行(why?)

先行发生happends-before原则

如果java内存模型中只能靠volatile和synchronize关键字来有序性的执行,那么有一些操作起来就会非常频繁,所以Java语言中有一种现行发生happens-before的原则,如下

程序次序规则:在一个线程内,按照控制流顺序,控制流前面的操作先行发生于控制流后面的操作,说“控制流”是因为还要考虑到分支、循环结构

管程锁定规则:unlock操作必须先行发生于同一个锁的lock操作

volatile规则:变量的写操作必须先于读操作

线程启动规则:thread的start()方法先于任何方法

线程终止规则:线程中的所有方法都先行与对此线程终止检测

线程中断规则:对线程的interrupt()方法调用先行发生于被中断线程的代码检测到中断事件的发生

对象终结规则:对象的初始化完成必须先发生于finalize()方法的开始

传递新:A操作先于B操作,B操作先于C操作,则A操作一定先于C操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值