gpt4 book ai didi

java - 为什么要对两个 volatile 变量进行重新排序?

转载 作者:行者123 更新时间:2023-12-01 20:22:46 26 4
gpt4 key购买 nike

我正在尝试研究 java 环境中重新排序的行为(使用 JDK 9-ea+170),并发现一件事我无法为自己解释,所以我很高兴听到一些关于它的注释。这是一个例子:

public class Client {
int x;
int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}

该程序有一个 test() 方法,该方法仅递增 x 和 y 值。我正在创建新线程并调用此 test() ,直到某些内部 java 优化不会更改 x++; 的顺序; y++; 指令()。这样我就证明重新排序确实发生了。并且程序大部分时间都会结束(这是预期的)。 现在我已经向 y 添加了 volatile 修饰符:

public class Client {
int x;
volatile int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}

这个程序永远不会结束,因为 volatile 保证 volatile 之前的所有指令都将被刷新到内存中,因此 x++; 总是在 y++; 之前执行,并且不可能有 y > x。这也是我的理解所预料的。但之后我也向 int x; 添加了 volatile,现在我可以再次看到重新排序,因此程序大部分时间都会结束:

public class Client {
volatile int x;
volatile int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}

为什么这里还要进行重新排序?

最佳答案

这不是重新排序的证据。事实上,正在发生的事情是 ++ 的结果。在volatile上不是原子的。例如,在更新变量之一 ( A ) 时,考虑两个线程 ( Bx ) 的以下交错操作:

thread A: load x -> temp
thread B: load x -> temp
thread A: temp = temp + 1
thread B: temp = temp + 1
thread A: save temp -> x
thread B: save temp -> x

如果您通过该交错完成这些操作,您会发现您已经失去了 x 的计数。 。这对于 c.y <= c.x 来说就足够了偶尔会失败。

(“丢失计数”行为也可能发生在 y 上……这解释了为什么此实验仅在某些时候失败。)

关于java - 为什么要对两个 volatile 变量进行重新排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44351854/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com