Happens-Before原则
Java内存模型是通过各种操作来定义的,包括对变量的读/写操作,监视器的加锁和释放操作,以及线程的启动和合并操作。JMM为程序中所有的操作定义了一个偏序关系,称之为Happens-Before。要想保证执行操作B的线程看到操作A的结果(无论A和B是否在同一个线程中执行),那么A和B之间必须满足Happens-Before关系。如果两个操作之间缺乏Happens-Before关系,那么JVM可以对它们任意地重排序。
当一个变量被多个线程读取并且至少被一个线程写入时,如果在读操作和写操作之间没有按照Happens-Before来排序,那么就会产生数据竞争问题。在正确同步的程序中不存在数据竞争,并会表现出串行一致性,这意味着程序中的所有操作都会按照一种固定的和全局的顺序执行。
Happens-Before规则:
- 程序顺序规则:如果程序中操作A在操作B之前,那么线程中A操作将在B操作之前执行。
- 监视器锁规则:对一个锁的解锁操作必须在随后对这个锁的加锁操作之前执行。
- volatile变量规则:对volatile变量的写入操作必须在对该变量的读操作之前执行。
- 线程启动规则:在线程上对Tread.start()的调用必须在该线程中执行任何操作之前执行。
- 线程结束规则:线程中的任何操作都必须在其他线程中检测到该线程已经结束之前执行,或者从Thread.join()中成功返回,或者在调用Thread.isAlive()时返回false。
- 如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作在线程A从ThreadB.join()操作成功返回之前执行。
- 中断规则:当一个线程在另一个线程上调用interrupt()时,必须在被中断线程检测到interrupt()调用之前执行。(通过抛出InterruptException,或者调用isInterrupted和interrupted)
- 终结器规则:对象的构造函数必须在启动该对象的终结器(finalize())之前执行完成。
- 传递性:如果操作A在操作B之前执行,并且操作B在操作C之前执行,那么操作A必须在操作C之前执行。
两个线程在使用同一个锁进行同步时,在它们之间的Happens-Before关系:在县城A内部的所有操作都按照它们在源程序中的先后顺序来排序,在线程B内部的操作也是如此。由于A释放了锁M,并且B随后获取了锁M,因此A中所有在释放锁之前的操作,也就位于B中请求锁之后的所有操作之前。
如果这两个线程是在不同的锁上进行同步的,那么就不能推断出他们之间的动作顺序,因为在这两个线程的操作之间并不存在Happens-Before关系。
Happens-Before原则的更多相关文章
- javascript的api设计原则
前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...
- 让姑姑不再划拳 码农也要有原则 : SOLID via C#
“姑娘,别这样.我们是有原则的.” “一个有原则的程序猿是不会写出 “摧毁地球” 这样的程序的,他们会写一个函数叫 “摧毁行星”而把地球当一个参数传进去.” “对,是时候和那些只会滚键盘的麻瓜不同了, ...
- java面向对象六原则一法则
1. 单一职责原则:一类只做它该做的事. 2. 里氏替换原则:子类必须能够替换基类(父类),否则不应当设计为其子类. 3. 依赖倒换原则:设计要依赖于抽象而不是具体化. 4. 接口隔离原则:接口要小而 ...
- SOLID 设计原则
SOLID 原则基本概念: 程序设计领域, SOLID (单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期 引入的记忆术首字母缩略字,指代了面向对象编程和面向对象 ...
- Java程序员应该了解的10个面向对象设计原则
面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorat ...
- Atitit.研发团队的管理原则---立长不立贤与按资排辈原则
Atitit.研发团队的管理原则---立长不立贤与按资排辈原则 1. 组织任命原则概述1 2. 历史的角度看,大部分组织使用的立长不立贤原则1 3. 论资排辈 立长不立贤原则1 3.1. 资格和辈分是 ...
- DIP原则、IoC以及DI
一.DIP原则 高层模块不应该依赖于底层模块,二者都应该依赖于抽象. 抽象不应该依赖于细节,细节应该依赖于抽象. 该原则理解起来稍微有点抽象,我们可以将该原则通俗的理解为:"依赖于抽象&qu ...
- TDD原则
TDD 介绍 测试驱动开发,或者叫 TDD,是一个敏捷方法,通过确保在代码是先前手动编写测试用 例,用测试来驱动开发,从而翻转开发生命周期(它不只是作为一种校验工具). TDD 的原则很简单的: 只有 ...
- 【PRINCE2是什么】PRINCE2认证之七大原则(7)
我们先来回顾一下,PRINCE2七大原则分别是持续的业务验证,经验学习,角色与责任,按阶段管理,例外管理,关注产品,剪裁 第七个原则:根据项目环境剪裁 PRINCE2的价值在于它是一个通用的项目管理方 ...
- 【PRINCE2是什么】PRINCE2认证之七大原则(6)
我们先来回顾一下,PRINCE2七大原则分别是持续的业务验证,经验学习,角色与责任,按阶段管理,例外管理,关注产品,剪裁 第六个原则:关注产品 PRINCE2指出,一个成功的项目必须以产品为导向,而不 ...
随机推荐
- 自定义reaml创建使用实现认证
注意清空shiro.ini 创建User对象 package cn.zys.Bean; public class User { private Integer id; private String u ...
- 解释一下,@SpringBootApplication
解释一下,@SpringBootApplication其实就是以下三个注解的总和 @Configuration: 用于定义一个配置类 @EnableAutoConfiguration :Spring ...
- lin-cms-dotnetcore.是如何方法级别的权限控制的?
方法级别的权限控制(API级别) Lin的定位在于实现一整套 CMS的解决方案,它是一个设计方案,提供了不同的后端,不同的前端,而且也支持不同的数据库 目前官方团队维护 lin-cms-vue,lin ...
- 浅谈进程&线程
学习过操作系统(下面简称OS)的都清楚,计算机计算的核心是CPU,操作系统是计算机资源的管理者 同事也是软硬件之间的接口.为了实现程序的并发,而引入了进程的概念.在传统OS中,进程是个很重要的概念,它 ...
- [Objective-C] 015_Delegate(委托代理)
Delegate在iOS开发中随处可见,Delegate是一种功能强大的软件架构设计理念,它的功能是程序中一个对象代表另一个对象,或者一个对象与另外一个对象协同工作(如小明喜欢一个女孩如花,却苦于没有 ...
- 同步锁Lock & 生产者和消费者案例
显示锁 Lock ①在 Java 5.0 之前,协调共享对象的访问时可以使用的机 制只有 synchronized 和 volatile . Java 5.0 后增加了一些 新的机制,但并不是一种替代 ...
- centos6.4中文输入法
在虚拟机中装了centos6.4之后,一直使用命令行,没有用到编辑器编辑中文或者浏览器中文搜索,所以没有注意到里边中文输入的重要性.在网上有看到说如果用的是中文版本应该有自带的中文输入法,然后用快捷键 ...
- 大型可视化项目用什么工具好呢?——不如了解一下阿里云DataV尊享版
随着信息化的发展和进步,可视化大屏开始为社会各行业提供全面应用.目前越来越多的需求显示希望大屏能够更直观的还原出所要展示数据可视化的真实场景,让整个项目更立体.更有科技感,让项目在面对复杂操作时能灵活 ...
- Java实现 蓝桥杯 算法提高 特等奖学金(暴力)
试题 算法提高 特等奖学金 问题描述 土豪大学每年都会给学生颁发巨额的特等奖学金,当然,获奖的前提是要足够优秀.这所大学有n名学生,他们中的每个人都会在m门必修课的每门课上获得一个百分制的整数成绩(0 ...
- Java实现 LeetCode 526 优美的排列(DFS)
526. 优美的排列 假设有从 1 到 N 的 N 个整数,如果从这 N 个数字中成功构造出一个数组,使得数组的第 i 位 (1 <= i <= N) 满足如下两个条件中的一个,我们就称这 ...