我正在阅读B. Goetz Java Concurrency在实践中,现在我正处于section 3.5安全的出版物中.他说:
// Unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
Run Code Online (Sandbox Code Playgroud)
这种不正确的发布可能允许另一个线程观察部分构造的对象.
我不明白为什么可以观察到部分构造的子对象.假设构造函数Holder(int)不允许this转义.因此,构造的引用只能由调用者观察到.现在,正如JLS 17.7所述:
无论是否将它们实现为32位或64位值,对引用的写入和读取始终是原子的.
线程不可能观察到部分构造的对象.
我哪里错了?
在《 Java并发实践》一书中,您可以找到以下代码:
@ThreadSafe
public class SafePoint {
@GuardedBy("this") private int x, y;
private SafePoint(int[] a) { this(a[0], a[1]); }
public SafePoint(SafePoint p) { this(p.get()); }
public SafePoint(int x, int y) {
this.x = x;
this.y = y;
}
public synchronized int[] get() { return new int[] { x, y };
}
public synchronized void set(int x, int y) { this.x = x;
this.y = y;
}
}
Run Code Online (Sandbox Code Playgroud)
此标记为 @ThreadSafe。
我很确定此类不是线程安全的(如果我正确理解了这个术语的话)。
例:
SafePoint racePublishedSafePoint; // field
// thread 1:
racePublishedSafePoint …Run Code Online (Sandbox Code Playgroud)