我想确保我根据 Java 内存模型正确理解了“有效不可变对象(immutable对象)”的行为。
假设我们有一个可变类,我们希望将其发布为有效的不可变类:
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 Concurrency In Practice 这应该是真的,但如果我错了,请纠正我。
3.5.3. Safe Publication Idioms
To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:
- Initializing an object reference from a static initializer;
- Storing a reference to it into a volatile field or AtomicReference;
- Storing a reference to it into a final field of a properly constructed object; or
- Storing a reference to it into a field that is properly guarded by a lock.3.5.4. Effectively Immutable Objects
Safely published effectively immutable objects can be used safely by any thread without additional synchronization.
最佳答案
是的。 MutableLong
上的写入操作之后是读取之前的 happens-before
关系(在 volatile 上)。
(一个线程可能会读取 Outworld.published
并将其不安全地传递给另一个线程。理论上,这可以看到更早的状态。实际上,我没有看到它发生。 )
关于java - 有效不可变对象(immutable对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10254456/