java - JIT 是这种行为的原因吗?

标签 java multithreading jit non-volatile

受此启发question ,我写了测试:

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);
        }
    }
}

这个程序在普通情况下被打印出来:

nonEqualsCount = 12; //or other non 0 value;
nonEqualsCount = 0;
nonEqualsCount = 0;
nonEqualsCount = 0;
nonEqualsCount = 0;

首先:我解释这种行为是因为 JIT 编译器的存在。 “预热”后每个线程的 JIT 编译器缓存值非 volatile 字段。对吗?

第二:如果第一对不对,如何验证?

附言- 我知道 PrintAssebly-选项。

更新:环境:Windows 7 64 位,JDK 1.7.0_40-b43(热点)。

最佳答案

递增 long 变量不是原子的(64 位大)。 在条件 (value != value) 中:可能会发生在读取 value 的值之间,第一个线程可以更改值。 volatile 类型与visibility 相关。非 volatile 变量值可能是陈旧的。所以你的第一个结论似乎是正确的。

关于java - JIT 是这种行为的原因吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19807473/

相关文章:

java - 每个客户端一个线程是答案吗?

python - 如何加速 Numpy sum 和 Python for-loop?

c# - 强制 C# 编译器创建未使用的对象实例

java - 在 play 2.0 中加载 initial-data.yml 时出现问题

java - 抛出自定义异常时如何动态确定方法签名?

java - 为什么 Java synchronized 没有按预期工作?

c++ - 具有自定义 VideoCapturer 的 WebRTC native (C++) 无法通过 main_thread_.CalledOnValidThread() 检查

assembly - 用于 C 语言的完整 x86/x64 JIT 汇编程序

java - 使用 zxing 从图像中检测二维码

java - 为什么 OkHttp post 方法发送的是 get 请求而不是 post 请求?