[讨论] reorder的几个疑问求解惑
runshine
2012-10-18
reorder发生的时间点是在哪个阶段?
1.源码编译成bytecode时 2.bytecode被载入vm时 3.(interpreted mode)bytecode到instruction的阶段 (mixed mode)JIT生成native code时(或者是中间的某个阶段--比如汇编阶段),native code被执行时 --------------------------------------- volatile对reorder的影响 比如如下操作的顺序 int x1; long x2; volatile int y1; volatile long y2; int z1; long z2; reorder后 x系列与z系列,是否有可能被排到一起的可能(但是y系列之间的顺序不变化)?类似如下形式 long x2; int x1; int z1; long z2; volatile int y1; volatile long y2; 还是说volatile作为内存屏障,只有其上界的代码之间(或下界的代码之间)会发生reorder而自身之间不会发生?类似如下形式 long x2; int x1; volatile int y1; volatile long y2; long z2; int z1; ------------------------------------------- [volatile|final]对可变对象可见性的影响 [volatile|final] HashMap<Long,Long> map; 不做任何的线程同步 线程1: map.put(1L,1L); map.put(2L,2L); map.put(1L,-1L); 线程2是否会立即看到map的变化? 如果不能,如何才能让线程2立即看到变化? [volatile|final] long y2; 线程1: map.put(y2,y2); 可以吗? -------------------------------------------- 表述的不很清楚,希望不影响我表达的意思哈 ![]() |
|
RednaxelaFX
2012-10-18
runshine 写道 reorder发生的时间点是在哪个阶段?
1.源码编译成bytecode时 2.bytecode被载入vm时 3.(interpreted mode)bytecode到instruction的阶段 (mixed mode)JIT生成native code时(或者是中间的某个阶段--比如汇编阶段),native code被执行时 规范没对这种细节做规定。只要最终的“表现”能维持规范所规定的顺序即可。 所以理论上以上所有情况都可以发生。 现实中的Java, * 好多年之前开始Java源码编译到class文件的源码级编译器就已经不做重排序了。不是理论上不能做,只是投入-收益比不高所以大家都不做了而已。 * 类加载过程中会做字节码改写的VM不少见。至少HotSpot与JRockit都会对某些代码序列做改写,但不涉及重排序。 * 先对字节码做少量预处理/转换再解释执行的、以解释器来实现的JVM也是可以有的。如果在转换过程中做些重排序自然也是可以。不过HotSpot与J9都不做这个;JRockit不用解释器实现所以这里忽略。 * 从字节码到native code的动态编译时可能涉及大量重排序,HotSpot VM里的两个编译器所做的优化都有可能导致代码的重排,不过规范所规定的必须保证的同步/volatile顺序会有保证。 * CPU自身可能也是O-O-O(out-of-order)执行的。在这样的CPU上运行的JVM实现必须在合适的地方插入memory barrier来保证实际执行顺序与规范所规定的顺序一致。 |
|
runshine
2012-10-19
谢谢R大的解答.
![]() 分割线后的两个问题也无耻的恳请继续解答一下哈 ![]() |
|
xiaoyu
2012-10-19
runshine 写道 谢谢R大的解答.
![]() 分割线后的两个问题也无耻的恳请继续解答一下哈 ![]() 我无耻的答一下. 对于一个复杂对象, 他整体结构上不能保证可见性, 你用volatile修饰引用是没用的. 所以 1, 和2 ....都是不可以的. |
|
runshine
2012-10-19
xiaoyu 写道 runshine 写道 谢谢R大的解答.
![]() 分割线后的两个问题也无耻的恳请继续解答一下哈 ![]() 我无耻的答一下. 对于一个复杂对象, 他整体结构上不能保证可见性, 你用volatile修饰他的引用是没用的. 所以 1, 和2 ....都是不可以的. 谢谢,谢谢~你说的是第三个问题哈?[1, 和2 ....]指的是 引用 1: 线程1: map.put(1L,1L); map.put(2L,2L); map.put(1L,-1L); 线程2是否会立即看到map的变化? 2: 如果不能,如何才能让线程2立即看到变化? [volatile|final] long y2; 线程1: map.put(y2,y2); 这个么? |
|
xiaoyu
2012-10-19
runshine 写道 xiaoyu 写道 runshine 写道 谢谢R大的解答.
![]() 分割线后的两个问题也无耻的恳请继续解答一下哈 ![]() 我无耻的答一下. 对于一个复杂对象, 他整体结构上不能保证可见性, 你用volatile修饰他的引用是没用的. 所以 1, 和2 ....都是不可以的. 谢谢,谢谢~你说的是第三个问题哈?[1, 和2 ....]指的是 引用 1: 线程1: map.put(1L,1L); map.put(2L,2L); map.put(1L,-1L); 线程2是否会立即看到map的变化? 2: 如果不能,如何才能让线程2立即看到变化? [volatile|final] long y2; 线程1: map.put(y2,y2); 这个么? 恩, 是你写的关于map, 1和2的两种可见性问题. |
|
runshine
2012-10-19
xiaoyu 写道 恩, 是你写的关于map, 1和2的两种可见性问题.
哈哈~谢谢啦 还求第二个volatile对reorder影响问题的答案哈? 是第二种情况么? |
|
xiaoyu
2012-10-19
runshine 写道 xiaoyu 写道 恩, 是你写的关于map, 1和2的两种可见性问题.
哈哈~谢谢啦 还求第二个volatile对reorder影响问题的答案哈? 是第二种情况么? 对于这个, 我只能说, jvm中class存储的数据结构顺序, 和执行(初始化)顺序...不是一回事...(能了解波?) |
|
runshine
2012-10-19
xiaoyu 写道 runshine 写道 xiaoyu 写道 恩, 是你写的关于map, 1和2的两种可见性问题.
哈哈~谢谢啦 还求第二个volatile对reorder影响问题的答案哈? 是第二种情况么? 对于这个, 我只能说, jvm中class存储的数据结构顺序, 和执行(初始化)顺序...不是一回事...(能了解波?) 嗯...我不是这个意思,看来是我描述的太简略了. ![]() 那几个xyz,不是声明,而是对几种变量的操作的意思... x系列是在第一次出现volatile之前的一系列操作,z系列是最后一次出现volatile之后的一系列操作,y系列是几个无关的volatile变量的操作 public class VolatileReorder { int x1; long x2; int z1; long z2; volatile int y1; volatile long y2; public void exec(int arg) { x1 = arg+1; x2 = arg+2; y1 = arg+3; y2 = arg+4; z1 = arg+5; z2 = arg+6; } } 就是这样,reorder可能导致的实际顺序是什么? |
|
xiaoyu
2012-10-19
runshine 写道 xiaoyu 写道 runshine 写道 xiaoyu 写道 恩, 是你写的关于map, 1和2的两种可见性问题.
哈哈~谢谢啦 还求第二个volatile对reorder影响问题的答案哈? 是第二种情况么? 对于这个, 我只能说, jvm中class存储的数据结构顺序, 和执行(初始化)顺序...不是一回事...(能了解波?) 嗯...我不是这个意思,看来是我描述的太简略了. ![]() 那几个xyz,不是声明,而是对几种变量的操作的意思... x系列是在第一次出现volatile之前的一系列操作,z系列是最后一次出现volatile之后的一系列操作,y系列是几个无关的volatile变量的操作 public class VolatileReorder { int x1; long x2; int z1; long z2; volatile int y1; volatile long y2; public void exec(int arg) { x1 = arg+1; x2 = arg+2; y1 = arg+3; y2 = arg+4; z1 = arg+5; z2 = arg+6; } } 就是这样,reorder可能导致的实际顺序是什么? 这个, R大已经回答你了. 仔细看. (PS: 看看cpu如何支持volatile的, 不同的操作对应不同的memory barrier, 那么reorder 就有不同的规定的..) |