我希望确保我正确理解Java内存模型中“有效不可变对象”的行为。假设我们有一个可变类,我们想将其发布为有效不可变对象:
我们做以下事情:
class Outworld {
// This MAY be accessed by multiple threads
public static volatile MutableLong published;
}
// This class is mutable
class MutableLong {
private long value;
public MutableLong(long value) {
this.value = value;
}
public void increment() {
value++;
}
public long get() {
return value;
}
}
我们做以下事情:
// Create a mutable object and modify it
MutableLong val = new MutableLong(1);
val.increment();
val.increment();
// No more modifications
// UPDATED: Let's say for this example we are completely sure
// that no one will ever call increment() since now
// Publish it safely and consider Effectively Immutable
Outworld.published = val;
问题是:
Java内存模型是否保证所有线程都必须具有Outworld.published.get() == 3
?
根据Java并发实践,这应该是正确的,但如果我错了,请纠正我。
3.5.3. 安全发布惯用语
为了安全地发布对象,必须同时将对象的引用和对象状态对其他线程可见。可以通过以下方式安全地构造对象:
- 从静态初始化器初始化对象引用;
- 将引用存储到volatile字段或AtomicReference中;
- 将引用存储到正确构造的对象的final字段中;或
- 将引用存储到由锁正确保护的字段中。3.5.4. 有效不可变对象
安全发布的有效不可变对象可以被任何线程安全地使用,无需额外同步。