gpt4 book ai didi

java - 为什么同步的 getter 像 volatile read 一样工作?

转载 作者:搜寻专家 更新时间:2023-11-01 03:15:39 24 4
gpt4 key购买 nike

这个程序不会终止!

public class Main extends Thread {
private int i = 0;
private int getI() {return i; }
private void setI(int j) {i = j; }

public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.start();

Thread.sleep(1000);
main.setI(10);
}

public void run() {
System.out.println("Awaiting...");
while (getI() == 0) ;
System.out.println("Done!");
}
}

我知道发生这种情况是因为运行 Awaiting 循环的 CPU 核心总是看到 i 的缓存副本并错过了更新。

我也明白,如果我使 volatileprivate int i = 0; 那么 while (getI().. . 的行为[1] 就像每次查询主内存时一样 - 因此它将看到更新后的值,我的程序将终止。

我的问题是:如果我做

synchronized private int getI() {return i; }

它出人意料地有效!!程序终止。

我知道 synchronized 用于防止两个不同的线程同时进入一个方法 - 但这里只有一个线程曾经进入 getI()。这是什么魔法?

编辑 1

This (synchronization) guarantees that changes to the state of the object are visible to all threads

因此,我没有直接拥有私有(private)状态字段 i,而是进行了以下更改:

代替 private int i = 0; 我做了 private Data data = new Data();, i = j 更改为 data.i = j 并且 return i 更改为 return data .i

现在 getIsetI 方法不会对定义它们的对象的状态做任何事情(并且可能是同步的)。即使现在使用 synchronized 关键字也会导致程序终止!有趣的是知道其状态实际上正在改变的对象 (Data) 没有同步或任何内置的东西。那为什么?


[1] 它可能只是表现,我不清楚到底发生了什么

最佳答案

这只是巧合或平台依赖或特定的JVM依赖,JLS不保证。所以,不要依赖它。

关于java - 为什么同步的 getter 像 volatile read 一样工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54218376/

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