Java 两个相关可变变量的内存可见性语义

Java 两个相关可变变量的内存可见性语义,java,memory,volatile,jls,java-memory-model,Java,Memory,Volatile,Jls,Java Memory Model,从下面的示例中考虑以下程序: 假设两个线程同时执行方法one()和two() JLS声明如下: 这允许方法1和方法2同时执行,但是 保证访问i和j的共享值 与它们出现的次数和顺序完全相同 在每个线程执行程序文本期间发生。 因此,j的共享值永远不会大于i的共享值, 因为对i的每次更新都必须反映在i的共享值中 在更新到j之前。然而,任何给定的 调用方法2可能会观察到j的一个值,这个值非常大 大于为i观察到的值,因为方法1可能是 在方法2获取 i的值和方法2获取j值的时刻 我真的被上面的引文弄糊涂了,

从下面的示例中考虑以下程序:

假设两个线程同时执行方法
one()
two()

JLS声明如下:

这允许方法1和方法2同时执行,但是 保证访问i和j的共享值 与它们出现的次数和顺序完全相同 在每个线程执行程序文本期间发生。 因此,j的共享值永远不会大于i的共享值, 因为对i的每次更新都必须反映在i的共享值中 在更新到j之前。然而,任何给定的 调用方法2可能会观察到j的一个值,这个值非常大 大于为i观察到的值,因为方法1可能是 在方法2获取 i的值和方法2获取j值的时刻

我真的被上面的引文弄糊涂了,因为它说了两种相互矛盾的说法:

  • j
    的共享值大于
    i
    的共享值。 (我的重点)

  • j
    的值远大于
    i
    的观察值

  • 第一条语句对我来说很有意义,因为如果我们结合程序顺序规则(
    i++
    发生在
    j++
    之前)和volatile的内存可见性保证(发生在之前),我可以大致了解
    j
    的值不能超过
    i
    的原因。但是我不知道
    j
    的值怎么会远远超过
    I


    你能帮我理解这部分吗。

    在任何给定时刻,
    j
    的实际值都不能大于
    i
    的实际值。但是当声明

    System.out.println("i=" + i + " j=" + j);
    

    执行时,
    i
    j
    不会同时计算<代码>j在
    i
    之后计算。当计算
    i
    时,
    j
    小于或等于
    i
    。但是,当计算
    j
    时,另一个线程可能多次调用方法
    one()
    ,因此
    i
    j
    都可能会增加很多次。因此
    j
    仍然是
    在任何给定时刻
    j
    的实际值都不能大于
    i
    的实际值。但是当声明

    System.out.println("i=" + i + " j=" + j);
    

    执行时,
    i
    j
    不会同时计算<代码>j
    i
    之后计算。当计算
    i
    时,
    j
    小于或等于
    i
    。但是,当计算
    j
    时,另一个线程可能多次调用方法
    one()
    ,因此
    i
    j
    都可能会增加很多次。因此
    j
    仍然是
    在任何给定时刻
    j
    的实际值都不能大于
    i
    的实际值。但是当声明

    System.out.println("i=" + i + " j=" + j);
    

    执行时,
    i
    j
    不会同时计算<代码>j
    i
    之后计算。当计算
    i
    时,
    j
    小于或等于
    i
    。但是,当计算
    j
    时,另一个线程可能多次调用方法
    one()
    ,因此
    i
    j
    都可能会增加很多次。因此
    j
    仍然是
    在任何给定时刻
    j
    的实际值都不能大于
    i
    的实际值。但是当声明

    System.out.println("i=" + i + " j=" + j);
    
    执行时,
    i
    j
    不会同时计算<代码>j
    i
    之后计算。当计算
    i
    时,
    j
    小于或等于
    i
    。但是,当计算
    j
    时,另一个线程可能多次调用方法
    one()
    ,因此
    i
    j
    都可能会增加很多次。所以
    j
    仍然是