簡體   English   中英

在Java中對非易失性對象進行非易失性引用的行為

[英]The behaviour of making a non-volatile reference to a volatile object in Java

來自C / C ++,對於Java中的易失對象行為,我有些困惑。

我了解Java中的volatile具有兩個屬性:

  1. 不會將對象帶入緩存,始終將其保留在主內存中。
  2. 保證“事前”

但是我不確定如果對對象進行新的非易失性引用會發生什么。 例如,

class Example {
   private volatile Book b = null;

   public init() { b = new Book(...); }

   public use() {
     Book local = b;
     local.read();
   }
}

AFAIK,易失性表示b所引用的“書本對象”應位於主存儲器中。 編譯器可能在內部將引用實現為指針,因此b指針可能位於緩存中。 據我了解,volatile是對象的限定符,而不是引用/指針。

問題是:在使用方法中,本地引用不是可變的。 這個“本地”引用是否會將底層Book對象從主存儲器帶入緩存,從而使該對象不是“易失”的?

沒有“易失性對象”或“始終將其保留在主內存中”這樣的保證。

保證引用類型的所有volatile變量是,對該變量的寫入與對該變量的后續讀取之間將發生事前關聯。

由於關系發生在傳遞之前 ,因此它們適用於您的示例代碼,即對於b = new Book(...) ,對Book實例所做的所有修改都在引用寫入到b之前提交,因此對於Book local = b; local.read(); Book local = b; local.read(); 在編寫引用之前,保證read()可以看到其他線程所做的所有這些修改。

這並不意味着Book實例的內存是特殊的。 例如, 將引用寫入b 之后 ,對該實例所做的修改可能對其他線程可見或不可見,而其他線程可能僅感知其中的一部分,或者將它們視為以不同的順序進行查看。

因此,以哪種方式獲取對對象的引用並不重要,重要的是更改是在通過b發布對該對象的引用之前還是之后進行的。 同樣,只要在通過讀取b獲取引用之后進行對對象的讀取訪問,就無關緊要。

使用local.read(); 您正在通過局部變量localread()訪問對象,盡管this將訪問相同的引用,但重要的是您在讀取對象的狀態之前已通過讀取b獲得了該引用。

volatile是關於參考的,而不是對象。

它保證在另一個線程設置了b的值之后,任何讀取變量b線程都將獲得另一個線程分配給b的值,而不是某些緩存的值。

暫無
暫無

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

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