Java重排序和happens-before原则
来源:互联网 发布:小鱼儿域名www9911hk 编辑:程序博客网 时间:2024/04/29 03:53
重排序
重排序是编译器和处理器为了优化性能而对指令执行的顺序进行重排序。大多数现代处理器都会采用将指令乱序执行的方法,在条件允许的情况下,直接运行当前有能力立即执行的后续指令,避开获取下一条指令所需数据时造成的等待。通过乱序执行的技术,处理器可以大大提高执行效率。
也就是说程序的执行,并不是严格按照程序语句编写的顺序执行,在运行期间可能是被打乱的。
重排序发生位置
- 编译器重排序
- 指令级并行重排序
- 内存系统重排序
as-if-serial
程序在执行的时候发成重排序,那Java是如何保证程序正常执行的呢?
原因就是Java遵循as-if-serial语义,即单线程执行程序时,即使发生重排序,程序的执行结果不能被改变。
as-if-serial保证了Java程序在单线程运行的情况下,结果的正常,让我们看起来像是顺序执行的样子。
happens-before
为了使Java程序在各个平台执行正常,Java内存模型中规定了happens-before规则。happens-before的前后两个操作不会被重排序且后者对前者内存可见。
happens-before规则
- 程序次序规则: 线程中每个动作A都happens-before于该线程中的每一个动作B。那么在程序中,所有的动作B都能出现在A之后。
- 监视器锁法则: 对一个监视器的解锁happens-before于每个后续对同一监视器锁的加锁
- volatile变量法则:对volatile域的写入操作happens-before于每一个后续对同一个域的读写操作
- 线程启动法则: 在一个线程中,对于Thread.start的调用会happens-before于每个启动线程的动作。
- 线程终结法则: 线程中的任何动作都happens-before于其他线程检测到这个线程已经终结。
- 中断法则: 一个线程调用另一个线程的interrupt happens-before于被中断的线程发现中断。
- 终结法则: 一个对象的构造函数的结束happens-before于这个对象finalizer的开始。
- 传递性: 如果A happens-before于B,且B happens-before于C,则A happens-before于C
volatile
volatile有两个语义:
1. 多线程对于域的可见性
2. 禁止指令重排序
第二个禁止对volatile的指令重排序在上面已经说明,现在说明JVM使如何保证volatile的可见性。
Java在处理volatile读写操作时会加入相应的内存屏障,来保证一个读写的循序。
内存屏障
内存屏障(Memory Barrier,或有时叫做内存栅栏,Memory Fence)是一种CPU指令,用于控制特定条件下的重排序和内存可见性问题。Java编译器也会根据内存屏障的规则禁止重排序。
LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。
- Java重排序和happens-before原则
- Java内存 happens-before原则
- 指令重排序及Happens-before法则
- happens-before原则
- 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
- 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
- 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
- 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
- JMM——重排序与happens-before
- Java并发编程系列之五:happens-before原则
- Java并发编程系列之四:happens-before原则
- jvm的happens-before原则
- 通俗易懂讲解happens-before原则
- happens-before先行发生原则
- 通俗易懂讲解happens-before原则
- Java Happens-before法则
- Java多线程--happens-before
- 学习笔记之Java线程安全杂谈(中)——Java内存模型、happens-before原则和DCL问题
- http工作原理
- github客户端(Windows)的使用
- CentOS6.5安装与配置Mysql数据库
- 基于docker的 redis集群之主从复制
- 如何成为数据挖掘工程师
- Java重排序和happens-before原则
- MultiByteToWideChar和WideCharToMultiByte用法详解
- 数据压缩原理与应用 彩色空间转换 实验报告
- osx下常用工具
- Android开发时,那些相见恨晚的工具或网站!感觉很好,后续自己也会补充点
- 洛谷1546 Agri-Net 最小生成树
- Git——Day1(基本概念)
- 大整数加法
- android studio设置指定的签名文件