happens-before原则定义如下:

1. 如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。

2. 两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则制定的顺序来执行。如果重排序之后的执行结果与按照happens-before关系来执行的结果一致,那么这种重排序并不非法。

下面是happens-before原则规则:

程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作;

锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作;

volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;

传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;

线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作;

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

线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;

对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;

我们来详细看看上面每条规则(摘自《深入理解Java虚拟机第12章》):

程序次序规则:一段代码在单线程中执行的结果是有序的。注意是执行结果,因为虚拟机、处理器会对指令进行重排序(重排序后面会详细介绍)。虽然重排序了,但是并不会影响程序的执行结果,所以程序最终执行的结果与顺序执行的结果是一致的。故而这个规则只对单线程有效,在多线程环境下无法保证正确性。

锁定规则:这个规则比较好理解,无论是在单线程环境还是多线程环境,一个锁处于被锁定状态,那么必须先执行unlock操作后面才能进行lock操作。

volatile变量规则:这是一条比较重要的规则,它标志着volatile保证了线程可见性。通俗点讲就是如果一个线程先去写一个volatile变量,然后一个线程去读这个变量,那么这个写操作一定是happens-before读操作的。

传递规则:提现了happens-before原则具有传递性,即A happens-before B , B happens-before C,那么A happens-before C

线程启动规则:假定线程A在执行过程中,通过执行ThreadB.start()来启动线程B,那么线程A对共享变量的修改在接下来线程B开始执行后确保对线程B可见。

线程终结规则:假定线程A在执行的过程中,通过制定ThreadB.join()等待线程B终止,那么线程B在终止之前对共享变量的修改在线程A等待返回后可见。

上面八条是原生Java满足Happens-before关系的规则,但是我们可以对他们进行推导出其他满足happens-before的规则:

将一个元素放入一个线程安全的队列的操作Happens-Before从队列中取出这个元素的操作

将一个元素放入一个线程安全容器的操作Happens-Before从容器中取出这个元素的操作

在CountDownLatch上的倒数操作Happens-Before CountDownLatch#await()操作

释放Semaphore许可的操作Happens-Before获得许可操作

Future表示的任务的所有操作Happens-Before Future#get()操作

向Executor提交一个Runnable或Callable的操作Happens-Before任务开始执行操作

这里再说一遍happens-before的概念:如果两个操作不存在上述(前面8条 + 后面6条)任一一个happens-before规则,那么这两个操作就没有顺序的保障,JVM可以对这两个操作进行重排序。如果操作A happens-before操作B,那么操作A在内存上所做的操作对操作B都是可见的。

java happens before_聊聊Java happens-before原则相关推荐

  1. java happens before_简单易懂讲解happens-before原则

    在接下来的叙述里我首先会说明happens-before规则是干什么用的,然后用一个简单的小程序说明happens-before规则 一.happens-before规则 我们编写的程序都要经过优化后 ...

  2. java异常_聊聊Java中的异常及处理

    前言 在编程中异常报错是不可避免的.特别是在学习某个语言初期,看到异常报错就抓耳挠腮,常常开玩笑说编程1分钟,改bug1小时.今天就让我们来看看什么是异常和怎么合理的处理异常吧! 异常与error介绍 ...

  3. java 物理内存_聊聊Java中的内存

    JVM的内存 先放一张JVM的内存划分图,总体上可以分为堆和非堆(粗略划分,基于java8) 那么一个Java进程最大占用的物理内存为: Max Memory = eden + survivor + ...

  4. java 异步_聊聊java高并发系统之异步非阻塞

    作者:孙伟,目前负责京东商品详情页统一服务系统,写过java,写过ngx_lua,还写过storm等,喜欢学习研究新事物. 在做电商系统时,流量入口如首页.活动页.商品详情页等系统承载了网站的大部分流 ...

  5. 《开源者说》08期:聊聊Java那些事儿

    <开源者说>08期:聊聊Java那些事儿 发表于2015-06-10 18:23| 4388次阅读| 来源CSDN| 28 条评论| 作者陈秋歌 Java开源者说 陈阳宫力许斌 摘要:20 ...

  6. Java设计模式GOF之6大设计原则

    Java设计模式GOF之6大设计原则原则 1.开闭原则(Open Close Principle) 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 开闭原则是面向对象的可复用设计的第一块基石 ...

  7. java开闭原则 例子_解析Java编程中设计模式的开闭原则的运用

    开闭原则(Open Closed Principle)是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的.灵活的系统. 定义: 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. S ...

  8. java虚拟机性能监控调优及原则

    转载自 https://www.cnblogs.com/thingk/p/6840585.html 摘抄 http://uule.iteye.com/blog/2114697 一.JVM内存模型及垃圾 ...

  9. gc java root_聊聊Java的GC机制

    原标题:聊聊Java的GC机制 近日,MIUI在小米全球社区发布公告,表示MIUI将在全球市场销售的手机中预装谷歌拨号及谷歌消息应用程序(中国.印度.印度尼西亚等市场除外).小米表示,小米9T Pro ...

最新文章

  1. 使用Python,OpenCV进行图像哈希
  2. .net core 2.1 发布到IIS遇到的问题
  3. 动态追踪技术思想及应用
  4. 【学习笔记】1、Python的基本介绍
  5. [CODEVS 1050] 棋盘染色 2
  6. Python网络编程(OSI模型、网络协议、TCP)
  7. LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)
  8. PHP实现二维码扫码登录
  9. 秒杀多线程第八篇 经典线程同步 信号量Semaphore
  10. 管理全局包、缓存和临时文件夹
  11. x264 的 cache详解
  12. Win7搭建NodeJs开发环境以及HelloWorld展示—图解
  13. Servlet添加商品
  14. 中国期货交易技术的逆袭之路
  15. 配置PotPlayer和Dolby Access启用耳机杜比全景声
  16. 为啥一到秋季就鼻塞、流鼻涕、打喷嚏?该如何是好?别总当成感冒
  17. uview 瀑布流_微信小程序 瀑布流布局
  18. 小数的二进制与十进制转换
  19. 血与泪的教训: JavaWeb中文乱码问题整合
  20. 让数字人出圈的技术秘籍,华为率先公开了

热门文章

  1. 去除蓝牙耳机回音(HT820)
  2. windows常用新建文件命令
  3. 解决qrcode生成的二维码华为手机长按不识别、toDataURL之后中间logo丢失等问题
  4. TBM610-ASEMI迷你贴片整流桥6A 1000V
  5. 解决Vue3的ts报错:类型“{}”上不存在属性“xxx”,两种方法彻底根治
  6. 江苏省计算机考试准考证号在哪查
  7. php每30分钟计算一次收益,Excel自动获取基金估值、计算当日收益和累计收益【2021/01/30更新】...
  8. 从一则IT新闻想到的
  9. 【loj2586】【APIO2018】选圆圈
  10. 单播 广播 组播区别