我读了几个相关的问题,但没有一个解释安全发布持有人的方法.我仍然对
Java Concurrency in Practice中的示例感到困惑,第3.5节:
有班主持人:
public Holder {
private int n;
public Holder(int n) { this.n = n };
public void assertSanity() {
if(n != n)
throw new AssertionError("This statement is false.");
}
}
及其不安全的出版物:
//unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
可能会抛出AssertionError,我同意.作者写道,这是因为不安全的出版物,但另一方面没有答案:
什么是正确的出版方式?
它们表示4种安全的出版习语,但我不明白,为什么它们会在上述情况下起作用:
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.
我同意1& 4,但怀疑为什么以下出版物会起作用:
//safe publication
public volatile Holder holder;
要么
//safe publication
public final Holder holder;
挥发性的final只对引用有影响,而不是引用的对象状态,所以我认为AssertionError仍然可能,对吧?
作者没有对出版物进行改进,而是通过以下方式展示如何使Holder免受不安全出版物的影响:
private final int n;
我很好奇以下是否也能奏效?它与(有效)不变性有何关联?
private volatile int n;
这是我的第一个问题,谢谢你的帮助!