先行发生原则(Happens-Before)是判断数据是否存在竞争、线程是否安全的主要依据。
先行发生是Java内存,模型中定义的两项操作之间的偏序关系,如果操作A先行发生于操作B,那么操作A产生的影响能够被操作B观察到。
 
Java内存模型中存在的天然的先行发生关系:
 
1. 程序次序规则:同一个线程内,按照代码出现的顺序,前面的代码先行于后面的代码,准确的说是控制流顺序,因为要考虑到分支和循环结构。
 
2. 管程锁定规则:一个unlock操作先行发生于后面(时间上)对同一个锁的lock操作。
 
3. volatile变量规则:对一个volatile变量的写操作先行发生于后面(时间上)对这个变量的读操作。
 
4. 线程启动规则:Thread的start( )方法先行发生于这个线程的每一个操作。
 
5. 线程终止规则:线程的所有操作都先行于此线程的终止检测。可以通过Thread.join( )方法结束、Thread.isAlive( )的返回值等手段检测线程的终止。 
 
6. 线程中断规则:对线程interrupt( )方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupt( )方法检测线程是否中断
 
7. 对象终结规则:一个对象的初始化完成先行于发生它的finalize()方法的开始。
 
8. 传递性:如果操作A先行于操作B,操作B先行于操作C,那么操作A先行于操作C。
 
总结:一个操作“时间上的先发生”不代表这个操作先行发生;一个操作先行发生也不代表这个操作在时间上是先发生的(重排序的出现)。
时间上的先后顺序对先行发生没有太大的关系,所以衡量并发安全问题的时候不要受到时间顺序的影响,一切以先行发生原则为准。

先行发生原则(Happens-before)的更多相关文章

  1. JAVA多线程之先行发生原则

    一.引子 如果java内存模型中所有的有序性都仅仅依靠volatile和synchronized来完成,那么有一些操作会变得很繁琐,但我们在编写java并发代码时并未感觉到这一点,这是因为java语言 ...

  2. java内存模型—先行发生原则

    Java语言中有一个“先行发生”(happens-before)的原则.这个原则非常重要,它是判断数据是否存在竞争,线程是否安全的主要依据,依赖这个原则,我们可以通过几条规则一揽子解决并发环境下两个操 ...

  3. Java之先行发生原则与volatile关键字详解

    volatile关键字可以说是Java虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确.完整地理解,以至于许多程序员都习惯不去使用它,遇到需要处理多线程数据竞争问题的时候一律使用synchro ...

  4. Happens-before先行发生原则

    简介 从JDK1.5,java使用新的JSR-133内存模型:JSR-133使用happens-before的概念来阐述操作之间的内存可见性:在JMM中,如果一个操作执行的结果需要对另一个操作可见,那 ...

  5. JVM-- 先行发生原则

    本文中需要的基础知识:指令重排 线程中两个非常重要的问题就是:原子性与可见性. 而下面的先行发生原则就是用来解决可见性问题的. 先行发生原则--是判断是否存在数据竞争.线程是否安全的主要依据. 先行发 ...

  6. Java内存模型相关原则详解

    在<Java内存模型(JMM)详解>一文中我们已经讲到了Java内存模型的基本结构以及相关操作和规则.而Java内存模型又是围绕着在并发过程中如何处理原子性.可见性以及有序性这三个特征来构 ...

  7. 深入理解 happens-before 原则

    在前面的文章中,我们深入了解了 Java 内存模型,知道了 Java 内存模型诞生的意义,以及其要解决的问题.最终我们知道:Java 内存模型就是定义了 8 个基本操作以及 8 个规则,只要遵守这些规 ...

  8. 40个Java多线程问题总结

    前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...

  9. JVM学习(3)——总结Java内存模型

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...

随机推荐

  1. C#HTTP POST文件数据

    /// <summary> /// 上传文件 /// </summary> /// <param name="uriStr">服务器网址< ...

  2. MFC之HTTP文件上传

    BOOL UploadFile(LPCTSTR strURL, LPCTSTR strLocalFileName) { // 如果URL为空或者文件不存在,直接返回 if (strURL == NUL ...

  3. php开启子进程处理

    $pageNum = ceil($totalNum/$pageSize); for($page=1;$page<=$pageNum;$page++){ $this->o_pcntl-> ...

  4. hibernate级联查询映射的两种方式

    Hibernate主要支持两种查询方式:HQL查询和Criteria查询.前者应用较为广发,后者也只是调用封装好的接口. 现在有一个问题,就是实现多表连接查询,且查询结果集不与任何一个实体类对应,怎么 ...

  5. SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  6. uvalive 6323 状态压缩DP

    思路:dp[i][j][x]表示状态 i 以 j 为结束 得分为 x 的方案数. #include<iostream> #include<cstdio> #include< ...

  7. mac 安装 maven 配置

    前面的话: 记录 在 Mac 下 安装配置 maven 1. 下载 Maven, 并解压到某个目录.例如/Users/robbie/apache-maven-3.3.3 2. 打开 Terminal, ...

  8. Perm 排列计数(bzoj 2111)

    Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic ...

  9. mysql启动错误1067的解决

    安装后MYSQL5后,发现启动出错,有时启动正常,但加接时马上出错. 出错代码:1067 解决办法如下: 删除%windows%/my.ini    删除其它地方的my.ini    在mysql安装 ...

  10. [LeetCode] Populating Next Right Pointers in Each Node 深度搜索

    Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...