[英]Why a synchronized getter work like a volatile read?
該程序不會終止!
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
的緩存副本並且錯過了更新。
我也明白,如果我使用volatile
private int i = 0;
然后while (getI()...
表現為[1]就像每次咨詢主內存一樣 - 所以它會看到更新的值,我的程序將終止。
我的問題是:如果我做的話
synchronized private int getI() {return i; }
它令人驚訝地工作! 該計划終止。
我知道synchronized
用於防止兩個不同的線程同時進入一個方法 - 但這里只有一個線程進入getI()
。 這是什么巫術呢?
編輯1
此(同步)保證對所有線程都可以看到對象狀態的更改
因此,而不是直接具有私有狀態字段i
,我做了以下變化:
代替 我做了private int i = 0;
private Data data = new Data();
, 更改為i = j
data.i = j
並更改為return i
return data.i
現在, getI
和setI
方法沒有對定義它們的對象的狀態做任何事情(並且可能是同步的)。 即使現在使用synchronized
關鍵字也會導致程序終止! 有趣的是知道狀態實際發生變化的對象( Data
)沒有同步或內置任何內容。 那么為什么?
[1]它可能只是表現為是,究竟是什么,真正發生的是我不清楚
它只是巧合或平台依賴或特定的JVM依賴,它不受JLS保證。 所以,不要依賴它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.