赞
踩
可以用 volatile
和 synchronized
来保证有序性。除此之外,JVM 还规定了先行发生原则,让一个操作无需控制就能先于另一个操作完成。
Single Thread rule
在一个线程内,在程序前面的操作先行发生于后面的操作。
Monitor Lock Rule
一个 unlock 操作先行发生于后面对同一个锁的 lock 操作。
Volatile Variable Rule
对一个 volatile 变量的写操作先行发生于后面对这个变量的读操作。
Thread Start Rule
Thread 对象的 start() 方法调用先行发生于此线程的每一个动作。
Thread Join Rule
Thread 对象的结束先行发生于 join() 方法返回。
Thread Interruption Rule
对线程 interrupt() 方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过 interrupted() 方法检测到是否有中断发生。
Finalizer Rule
一个对象的初始化完成(构造函数执行结束)先行发生于它的 finalize() 方法的开始。
Transitivity
如果操作 A 先行发生于操作 B,操作 B 先行发生于操作 C,那么操作 A 先行发生于操作 C。
问:Java内存模型中的先行发生原则中的程序次序规则:在一个线程内,按照程序代码顺序,书写在前的操作先行发生于书写在后的操作,这一点与程序编译中的指令重排优化是否矛盾?
答:java代码编写之后,到真正执行,会遇到三次的重排序,如下:
java代码-编译优化重排序-指令并行重排序-内存重排序-最终执行的指令序列
JMM ( JAVA 内存模型, java memory model) 为了保证在各种编译器、各种处理器下一致的内存可见性,会禁止特定类型的编译重排序,禁止特定类型的处理器重排序(指令、内存重排序都属于处理器重排序)。
周志明的《深入理解java虚拟机》的第12章12.3.6节中对程序次序原则是这么描述的:在一个线程内,按照程序代码顺序,书写在前的操作先行发生于书写在后的操作。准确的说应该是程序控制流顺序而不是程序代码顺序,因为要考虑分支、循环等结构。
指令重排序并不会修改程序的控制流顺序。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。