Cap*_*ngs 5 java memory concurrency constructor memory-fences
有人可以验证我对构造函数执行后建立的内存栅栏的理解.例如,假设我有一个名为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;
}
}
Run Code Online (Sandbox Code Playgroud)
此外,假设构造是由执行线程1,然后updateQty()
和updatePrice()
被称为若干时间线程2(总是由线程2).
我的论点是,在Thread1创建对象之后,对象的"可见性"与jvm中的所有其他线程建立.由于两个可变变量仅由Thread2更改,因此我不需要任何锁定.我对么?
我的论点是,在Thread1创建对象之后,对象的"可见性"与jvm中的所有其他线程建立.
这是不正确的.没有隐含的构造函数内存屏障/围栏,这就是构造函数周围的指令重新排序是一个问题.如果您要Stock
在构造它的其他线程中使用对象,则synchronize
在调用任何更新方法之前,您将不得不使用该对象.
由于两个可变变量仅由Thread2更改,因此我不需要任何锁定.
在最初同步对象之后,除非您想在其他线程中查看这些变异字段,否则Thread2
不需要任何其他锁定.如果多个线程正在从您的Stock
对象读取而在进行Thread2
变异时,则所有线程都需要通过同步或通过使字段变异字段来跨越内存屏障volatile
.
这必须同时使用构造函数操作重新排序和内存可见性.有关构造函数重新排序的更多缺陷,请参阅此答案: