Ser*_*zov 7 java multithreading jit non-volatile
受这个问题的启发,我写了测试:
public class Main {
private static final long TEST_NUMBERS = 5L;
private static final long ITERATION_NUMBER = 100000L;
private static long value;
public static void main(final String [] args) throws Throwable {
for(int i=0; i<TEST_NUMBERS; i++) {
value = 0;
final Thread incrementor = new Thread(new Incrementor());
final Thread checker = new Thread(new Checker());
incrementer.start();
checker.start();
checker.join();
incrementer.join();
}
}
static class Incrementor implements Runnable {
public void run() {
for(int i=0; i<ITERATION_NUMBER; i++){
++value;
}
}
}
static class Checker implements Runnable {
public void run() {
long nonEqualsCount = 0;
for(int i=0; i<ITERATION_NUMBER; i++){
if(value != value) {
++nonEqualsCount;
}
}
System.out.println("nonEqualsCount = " + nonEqualsCount);
}
}
}
Run Code Online (Sandbox Code Playgroud)
该程序以常见情况打印:
nonEqualsCount = 12; //or other non 0 value;
nonEqualsCount = 0;
nonEqualsCount = 0;
nonEqualsCount = 0;
nonEqualsCount = 0;
Run Code Online (Sandbox Code Playgroud)
第一:我解释这种行为是JIT编译器的存在.volatile"热备"后每个线程的JIT编译器缓存值非字段.对的?
第二:如果是对或不对,我该如何验证呢?
PS - 我知道PrintAssebly -option.
更新:环境:Windows 7 64位,JDK 1.7.0_40-b43(热点).
您所看到的可能是 JIT 的产物。在启动之前,Java 字节码会被解释,这意味着检查器线程在比较过程中有很多机会被中断。
此外,由于执行的代码较多,因此 CPU 缓存需要刷新的可能性也更高。
当代码被 JIT 优化时,它可能会插入 64 位操作,并且由于只执行少量代码,因此缓存将不再刷新到主内存,这意味着线程没有机会看到所做的更改由另一个。
| 归档时间: |
|
| 查看次数: |
321 次 |
| 最近记录: |