簡體   English   中英

為什么同步的getter像volatile一樣工作?

[英]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 = jreturn i更改為return data.i

現在, getIsetI方法沒有對定義它們的對象的狀態做任何事情(並且可能是同步的)。 即使現在使用synchronized關鍵字也會導致程序終止! 有趣的是知道狀態實際發生變化的對象( Data )沒有同步或內置任何內容。 那么為什么?


[1]它可能只是表現為是,究竟是什么,真正發生的是我不清楚

它只是巧合或平台依賴或特定的JVM依賴,它不受JLS保證。 所以,不要依賴它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM