JIT是出于这种行为的原因吗?

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(热点).

Aar*_*lla 2

您所看到的可能是 JIT 的产物。在启动之前,Java 字节码会被解释,这意味着检查器线程在比较过程中有很多机会被中断。

此外,由于执行的代码较多,因此 CPU 缓存需要刷新的可能性也更高。

当代码被 JIT 优化时,它可能会插入 64 位操作,并且由于只执行少量代码,因此缓存将不再刷新到主内存,这意味着线程没有机会看到所做的更改由另一个。