[英]The behaviour of making a non-volatile reference to a volatile object in Java
來自C / C ++,對於Java中的易失對象行為,我有些困惑。
我了解Java中的volatile具有兩個屬性:
但是我不確定如果對對象進行新的非易失性引用會發生什么。 例如,
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();
您正在通過局部變量local
和read()
訪問對象,盡管this
將訪問相同的引用,但重要的是您在讀取對象的狀態之前已通過讀取b
獲得了該引用。
volatile
是關於參考的,而不是對象。
它保證在另一個線程設置了b
的值之后,任何讀取變量b
線程都將獲得另一個線程分配給b
的值,而不是某些緩存的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.