[英]After an object is constructed, is a memory fence established with other threads?
有人可以驗證我對構造函數執行后建立的內存柵欄的理解。 例如,假設我有一個名為Stock的類。
public final class Stock{
private final String ticker;
private double qty;
private double price;
public Stock ( String ticker, double qty, double price ){
this.ticker = ticker;
this.qty = qty;
this.price = price;
//I am assuming a memory fence gets inserted here.
}
public final void updateQty( double qty ){
this.qty = qty;
}
public final void updatePrice( double price ){
this.price = price;
}
}
此外,假設構造是由線程1,然后執行updateQty()
和updatePrice()
由線程2(總是由線程2)被稱為若干時間。
我的論點是,在Thread1創建對象之后,對象的“可見性”與jvm中的所有其他線程建立。 由於兩個可變變量僅由Thread2更改,因此我不需要任何鎖定。 我對么?
我的論點是,在Thread1創建對象之后,對象的“可見性”與jvm中的所有其他線程建立。
這是不正確的。 沒有隱含的構造函數內存屏障/圍欄,這就是構造函數周圍的指令重新排序是一個問題。 如果您要在構造它的其他線程中使用Stock
對象,則必須在調用任何更新方法之前synchronize
該對象。
由於兩個可變變量僅由Thread2更改,因此我不需要任何鎖定。
在最初同步Thread2
的對象之后,除非您想在其他線程中查看這些變異字段,否則不需要任何其他鎖定。 如果多個線程正在從您的Stock
對象讀取而Thread2
正在改變它,那么所有線程都需要通過同步或通過使字段變異字段為volatile
來穿過內存屏障。
這必須同時使用構造函數操作重新排序和內存可見性。 有關構造函數重新排序的更多缺陷,請參閱此答案:
很不幸的是,不行。 構造函數(大多數)就像Java內存模型中的常規方法。
但這很糟糕,它給程序員帶來了無盡的困惑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.