码迷,mamicode.com
首页 > 移动开发 > 详细

Java深入学习03:happens-before规则

时间:2020-03-12 18:46:32      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:before   center   app   传递   volatil   情况下   加锁   col   volatile   

Java深入学习03:happens-before规则

为什么会有happens-before 规则?

因为jvm会对代码进行编译优化,指令会出现重排序的情况,为了避免编译优化对并发编程安全性的影响,需要happens-before规则定义一些禁止编译优化的场景,保证并发编程的正确性。

 

 

1. 规则一:程序的顺序性规则一个线程中,按照程序的顺序,前面的操作happens-before后续的任何操作。

对于这一点,可能会有疑问。顺序性是指,我们可以按照顺序推演程序的执行结果,但是编译器未必一定会按照这个顺序编译,但是编译器保证结果一定==顺序推演的结果

 

2. 规则二:volatile规则

对一个volatile变量的写操作,happens-before后续对这个变量的读操作。

 

3. 规则三:传递性规则

如果A happens-before B,B happens-before C,那么A happens-before C。

 

4.规则四:管程中的锁规则

对一个锁的解锁操作,happens-before后续对这个锁的加锁操作。

 

5.规则五:线程start()规则

主线程A启动线程B,线程B中可以看到主线程启动B之前的操作。也就是start() happens before 线程B中的操作。

 

6.规则六:线程join()规则

主线程A等待子线程B完成,当子线程B执行完毕后,主线程A可以看到线程B的所有操作。也就是说,子线程B中的任意操作,happens-before join()的返回。

 

这些规则背后的道理

在程序运行过程中,所有的变更会先在寄存器或本地cache中完成,然后才会被拷贝到主存以跨越内存栅栏(本地或工作内存到主存之间的拷贝动作),此种跨越序列或顺序称为happens-before。

注:happens-before本质是顺序,重点是跨越内存栅栏

通常情况下,写操作必须要happens-before读操作,即写线程需要在所有读线程跨越内存栅栏之前完成自己的跨越动作,其所做的变更才能对其他线程可见。

 

Java深入学习03:happens-before规则

标签:before   center   app   传递   volatil   情况下   加锁   col   volatile   

原文地址:https://www.cnblogs.com/wobuchifanqie/p/12475054.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!