gpt4 book ai didi

java - 并发变量修改 : cannot fully understand this example

转载 作者:行者123 更新时间:2023-11-29 09:52:37 24 4
gpt4 key购买 nike

我需要一些帮助来完全理解运行这段代码时发生了什么

public class Main extends Thread {

private static int x;

public static void main(String[] args) {
Thread th1 = new Main("A");
Thread th2 = new Main("B");
th1.start();
th2.start();
}

public Main(String n) {
super(n);
}

public void run() {
while(x<4) { //1
x++; //2
System.out.print(Thread.currentThread().getName()+x+" "); //3
}
}
}

我得到输出

B2 B3 B4 A2 

我知道线程 AB 都递增 x,然后 B 循环递增和输出.. .但为什么最后输出是A2?执行//3时,A不应该把x看成4吗?

附加问题:为什么x 不可能变成 5?

编辑

这个问题(形式略有不同)来自一个 OCP 认证的模拟测试,其中解释说 x 永远不会是 5。我很高兴看到我不是只有一个人不同意。

最佳答案

当您在一个线程中更新一个变量的值时,它的值不一定立即对所有线程可见。这是因为内存保存在 CPU 缓存中,这使得它的读写速度比主内存快得多。

周期性地,缓存的更新内容被复制到主内存。只有在发生这种情况时,其他线程才能看到值的更新。

这里看起来像是 B 正在更新值,但该值并未提交到主内存;因此,A 看到了它的旧值。

如果你使变量volatile ,所有读取和写入都是直接从/到主内存完成的(或者,至少,缓存从主内存刷新/刷新到主内存),因此对值的更新立即对所有线程可见。

但是请注意,您没有执行原子读写:另一个线程可以更新 x 的值在当前线程检查之间 x < 4并递增 x++ .因此,您最终可能会得到 5 的值。正在打印。

解决这个问题的最简单方法是使检查/递增同步:

synchronized (Main.class) {
if (x < 4) {
x++;
System.out.println(...);
}
}

这还具有确保对 x 更新的可见性的效果在所有线程中,但也确保只有一个线程可以检查/递增 x一次。

关于java - 并发变量修改 : cannot fully understand this example,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34745941/

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