再来重复下八大原则:

  • 单线程happen-before原则:在同一个线程中,书写在前面的操作happen-before后面的操作。
  • 锁的happen-before原则:同一个锁的unlock操作happen-before此锁的lock操作。
  • volatile的happen-before原则:对一个volatile变量的写操作happen-before对此变量的任意操作(当然也包括写操作了)。
  • happen-before的传递性原则:如果A操作 happen-before B操作,B操作happen-before C操作,那么A操作happen-before C操作。
  • 线程启动的happen-before原则:同一个线程的start方法happen-before此线程的其它方法。
  • 线程中断的happen-before原则:对线程interrupt方法的调用happen-before被中断线程的检测到中断发送的代码。
  • 线程终结的happen-before原则:线程中的所有操作都happen-before线程的终止检测。
  • 对象创建的happen-before原则:一个对象的初始化完成先于他的finalize方法调用。

首先在看本文前,最好先看下《java并发编程实战》之java内存模型这篇文章,对java内存模型有个了解。
happen-before 在这里不能理解成在什么之前发生,它和时间没有任何关系。个人感觉解释成“生效可见于” 更准确。下面通过对这八个原则详细解释来加深对“生效可见于”的理解。


在同一个线程中,书写在前面的操作happen-before后面的操作: 好多文章把这理解成书写在前面先发生于书写在后面的代码,但是指令重排序,确实可以让书写在后面的代码先于书写在前面的代码发生。这是里把happen-before 理解成“先于什么发生”,其实happen-beofre在这里没有任何时间上的含义。比如下面的代码:

int a = 3;      //1
int b = a + 1; //2

这里 //2 对b赋值的操作会用到变量a,那么java的“单线程happen-before原则”就保证 //2的中的a的值一定是3,而不是0,5,等其他乱七八糟的值,因为//1 书写在//2前面, //1对变量a的赋值操作对//2一定可见。因为//2 中有用到//1中的变量a,再加上java内存模型提供了“单线程happen-before原则”,所以java虚拟机不许可操作系统对//1 //2 操作进行指令重排序,即不可能有//2 在//1之前发生。但是对于下面的代码:

int a = 3;
int b = 4;

两个语句直接没有依赖关系,所以指令重排序可能发生,即对b的赋值可能先于对a的赋值。


同一个锁的unlock操作happen-beofre此锁的lock操作: 话不多说直接看下面的代码:

public class A {public int var;private static A a = new A();private A(){}public static A getInstance(){return a;}public synchronized void method1(){var = 3;}public synchronized void method2(){int b = var;}public void method3(){synchronized(new A()){ //注意这里和method1 method2 用的可不是同一个锁哦var = 4;}}
}
//线程1执行的代码:
A.getInstance().method1();
//线程2执行的代码:
A.getInstance().method2();
//线程3执行的代码:
A.getInstance().method3();

如果某个时刻执行完“线程1” 马上执行“线程2”,因为“线程1”执行A类的method1方法后肯定要释放锁,“线程2”在执行A类的method2方法前要先拿到锁,符合“锁的happen-before原则”,那么在“线程2”method2方法中的变量var一定是3,所以变量b的值也一定是3。但是如果是“线程1”、“线程3”、“线程2”这个顺序,那么最后“线程2”method2方法中的b值是3,还是4呢?其结果是可能是3,也可能是4。的确“线程3”在执行完method3方法后的确要unlock,然后“线程2”有个lock,但是这两个线程用的不是同一个锁,所以JMM这个两个操作之间不符合八大happen-before中的任何一条,所以JMM不能保证“线程3”对var变量的修改对“线程2”一定可见,虽然“线程3”先于“线程2”发生。


对一个volatile变量的写操作happen-before对此变量的任意操作:

volatile int a;
a = 1; //1
b = a;  //2

如果线程1 执行//1,“线程2”执行了//2,并且“线程1”执行后,“线程2”再执行,那么符合“volatile的happen-before原则”所以“线程2”中的a值一定是1。


如果A操作 happen-before B操作,B操作happen-before C操作,那么A操作happen-before C操作:如果有如下代码块:

volatile int var;
int b;
int c;
b = 4; //1
var = 3; //2
c = var; //3
c = b; //4

假设“线程1”执行//1 //2这段代码,“线程2”执行//3 //4这段代码。如果某次的执行顺序如下:
//1 //2 //3 //4。那么有如下推导( hd(a,b)表示a happen-before b):

因为有hd(//1,//2) 、hd(//3,//4) (单线程的happen-before原则)
且hd(//2,//3) (volatile的happen-before原则)
所以有 hd(//1,//3),可导出hd(//1,//4) (happen-before原则的传递性)
所以变量c的值最后为4
如果某次的执行顺序如下:
//1 //3 //2// //4 那么最后4的结果就不能确定喽。其原因是 //3 //2 直接符合上述八大原则中的任何一个,不能通过传递性推测出来什么。


通过对上面的四个原则的详细解释,省下的四个原则就比较显而易见了。这里就不做详细解释了。欢迎积极留言大家一起讨论。

作者:aworker
链接:https://www.jianshu.com/p/1508eedba54d

java 8大happen-before原则超全面详解相关推荐

  1. java 4大作用域_JavaWeb的四大作用域详解

    1.page指当前页面有效.在一个jsp页面里有效 2.request 指在一次请求的全过程中有效,即从http请求到服务器处理结束,返回响应的整个过程,存放在HttpServletRequest对象 ...

  2. Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载)

    Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载) 说明:主要是针对一些中大型的项目需要进行分布式以及负载均衡的架构提一些思路与建议. 面对大量用户访问.高并发请求,海量 ...

  3. java工程在windows环境用bat启动详解

    原 java工程在windows环境用bat启动详解 2016年08月24日 13:19:52 qq_31197461 阅读数:3038 <span class="tags-box a ...

  4. java path类_基于java Files类和Paths类的用法(详解)

    Java7中文件IO发生了很大的变化,专门引入了很多新的类: import java.nio.file.DirectoryStream; import java.nio.file.FileSystem ...

  5. java中sleep()、wait()相同与不同详解

    java中sleep().wait()相同与不同详解 相同 java中Thread#sleep和Object#wait方法都是暂停当前线程,当前线程让出CPU占用.并不存在调用sleep后还占用CPU ...

  6. hadoop大数据平台架构之DKhadoop详解

    hadoop大数据平台架构之DKhadoop详解 大数据的时代已经来了,信息的爆炸式增长使得越来越多的行业面临这大量数据需要存储和分析的挑战.Hadoop作为一个开源的分布式并行处理平台,以其高拓展. ...

  7. 蓝桥杯 Java B组 省赛决赛模拟赛 详解及小结汇总+题目下载【2013年(第4届)~2021年(第12届)】

    蓝桥杯 Java B组 省赛决赛模拟赛 详解及小结汇总+题目下载[2013年(第4届)~2021年(第12届)] 百度网盘-CSDN蓝桥杯资料(真题PDF+其它资料)   提取码:6666 2013年 ...

  8. Java中的宏变量,宏替换详解。

    转载自 Java中的宏变量,宏替换详解. 群友在微信群讨论的一个话题,有点意思,特拿出来分享一下. 输出true false 来看下面这段程序,和群友分享的大致一样. public static vo ...

  9. 大数据技术Hbase 和 Hive 详解

    目录 两者的特点 各自的限制 应用场景 大数据技术Hbase 和 Hive 详解, 今天给大家介绍一下关于零基础学习大数据视频教程之HBASE 和 HIVE 是多么重要的技术,那么两者有什么区别呢 ? ...

最新文章

  1. 【opencv】(13) 案例:停车场空余车位检测,附python完整代码
  2. 预备作业02 20162320刘先润
  3. Windows8应用生命周期 Metro Style Apps Lifecycle
  4. 信息系统项目管理师-论文要求
  5. php程序访问mysql数据实现查询_PHP+MySql实现后台数据的读取
  6. JAVA设计模式--简单介绍
  7. Railgun工具箱HWID验证
  8. 时间格式转换y-m-d
  9. nsga2代码解读python_代码资料
  10. 批处理学习之Bat命令——获取当前盘符、当前目录、上级目录
  11. 程序设计习惯养成计划---一、方法规约设计
  12. 自己动手写PHP MVC框架
  13. 北京上海等昨天大规模断网 专家称与太阳无关
  14. VS2008 安装失败(“Web 创作组件”无法)
  15. 模拟电子技术基础:基本放大电路
  16. Base64编码原理分析
  17. Java 检测字符是否存在手机号或返回该手机号
  18. java调用cmd且隐藏窗口,最后关闭窗口
  19. office2016兼容mathtype问题
  20. 谷歌变坏了?Chrome 已成众矢之的:15 篇前端热文回看

热门文章

  1. 一些让人受益匪浅的话--转
  2. pack()函数中类型对应的符号标记
  3. 百分点大数据技术团队:乘风破浪 海外数据中台项目实践
  4. 李开复:数位革命——创新创业的黄金时代
  5. 从呼叫中心到移动互联网的演进
  6. 深入理解分布式技术 - 探究缓存穿透、缓存击穿、缓存雪崩解决方案
  7. Spring5源码 - 00 IOC容器创建_前期准备
  8. Spring OXM-XStream转换器
  9. Java-Java5.0注解解读
  10. 基础JavaScript_Day04