JMM——重排序与happens-before
2016-03-30 09:49
441 查看
数据依赖性
如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。数据依赖分为下列三种类型:上述三种情况,只要重排序两个操作的执行顺序,程序的执行结果将会被改变
只有编译器和处理器在重排序时会遵守数据依赖性,它们不会改变存在数据依赖性关系的两个操作的执行顺序。
但是不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑
as-if-serial
语义:不管怎么重排序,单线程程序的执行结果不能被改变。如果操作之间不存在数据依赖关系,这些操作就可能被编译器和处理器重排序。
JSR-133内存模型
在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系1.程序顺序规则:一个线程中的操作,happens-before于该线程中的任意后续操作
2. 监视器锁规则:对一个监视器的解锁,happens-before与随后对这个监视器的加锁
3. volatile变量规则:对一个volatile域的写,happens-before与任意后续对这个volatile域的读
4. 传递性:如果A h-b B,且 B h-b C,那么 A h-b C
两个操作之间具有happens-before关系,并不意味着前一个操作必须要在后一个操作之后执行!
happens-before仅仅要求前一个操作的结果对后一个操作可见,且前一个操作按顺序排在第二个操作之前
程序顺序规则
根据happens-before的程序顺序规则,上面的实例代码存在三个happens-before关系:
1.A happens-before B
2.B happens-before C
3.A happens-before C
A happens-before C是推倒出来的
这里A happens-before B,但实际执行时B却可以排在A之前执行。
重排序A操作和B操作后对执行结果并没有影响,JMM会认为这种重排序并不非法,JMM允许这种重排序
在计算机中,软件技术和硬件技术有一个共同的目标:在不改变程序执行结果的前提下,尽可能地开发并行度
相关文章推荐
- JAVA中JVM的重排序详细介绍
- 深入理解java内存模型(二)重排序
- Java线程可见性
- The Java™ Tutorials — Concurrency :Memory Consistency Errors 内存一致性错误
- JMM——重排序与内存屏障
- Java内存模型jsr-133-faq
- java.util.concurrent包介绍(3)——Happens-before法则
- 先行发生原则(Happens-before)
- 深入理解Java内存模型(二)——重排序
- 为了防止程序重排序,慎用volatile 推荐
- 二:并发编程-重排序
- 可见性.重排序
- 美团推荐算法实践
- Java多线程 -- JUC包源码分析8 -- 对happen before的深刻理解
- Java多线程 -- JUC包源码分析3-- volatile/final语义
- java内存模型
- Java内存模型小析之重排序(三)
- Java并发编程 之 指令重排序
- Volatile关键字与线程安全
- 【Java线程】Java内存模型总结