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
仍然是