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指出,一个成功的项目必须以产品为导向,而不 ...
随机推荐
- MarkDown语法使用(效果版本)
function syntaxHighlighting() { var n = 33; var s = "hello, こんにちは"; console.log(s); } plai ...
- 伪静态%{REQUEST_FILENAME} !-f 和!-d用法
%{REQUEST_FILENAME} !-f 和!-d只对下一条RewriteRule起作用.再往下的RewriteRule不管用. -f 表示为文件 -d 表示为目录 ! 表示非,取反的意思 R ...
- Cypress系列(3)- Cypress 的初次体验
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前言 这里的栗子项目时 Cypress ...
- 副业收入是我做程序媛的3倍,工作外的B面人生
到“程序员”,多数人脑海里首先想到的大约是:为人木讷.薪水超高.工作枯燥…… 然而,当离开工作岗位,撕去层层标签,脱下“程序员”这身外套,有的人生动又有趣,马上展现出了完全不同的A/B面人生! 不论是 ...
- Golang模拟用户登陆,突破教务系统
目录 一.Golang模拟用户登陆,突破教务系统 1.1 请求登陆页面 1.2 抓包分析登陆请求 1.3 golang使用js引擎合成salt 1.4 模拟表单提交,完成登陆 1.5 进入成绩查询页, ...
- Chisel3 - Tutorial - Parity
https://mp.weixin.qq.com/s/OtiQnE52PwdCpvmzJ6VFnA 奇偶发生器.统计输入中1的个数,如果为偶数则输出0,奇数则输出1. 参考链接: https: ...
- PELT(Per-Entity Load Tracking)
引言 对于Linux内核而言,做一款好的进程调度器是一项非常具有挑战性的任务,主要原因是在进行CPU资源分配的时候必须满足如下的需求: 1.它必须是公平的 2.快速响应 3.系统的throughput ...
- Java实现 LeetCode 748 最短完整词(字母拆分+暴力)
748. 最短完整词 如果单词列表(words)中的一个单词包含牌照(licensePlate)中所有的字母,那么我们称之为完整词.在所有完整词中,最短的单词我们称之为最短完整词. 单词在匹配牌照中的 ...
- Java实现 蓝桥杯算法提高金明的预算方案
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元 ...
- java实现整数翻转
** 整数翻转** 以下程序把一个整数翻转(8765变为:5678),请补充缺少的代码. int n = 8765; int m = 0; while(n>0) { m = __________ ...