在 Java Concurrency In Practice 中,作者指出
- 不可变对象可以通过任何机制发布
- 任何线程都可以安全地使用不可变对象,而无需额外的同步,即使不使用同步来发布它们也是如此。
这是否意味着以下成语可以安全地发布不可变对象?
public static List<ImmutableObject> list = new ArrayList<ImmutableObject>();
// thread A invokes this method first
public static void methodA () {
list.add(new ImmutableObject());
}
// thread B invokes this method later
public static ImmutableObject methodB () {
return list.get(0);
}
会有数据竞赛吗?(这意味着线程 B 可能无法在线程 A 添加的列表中看到不可变对象)
非常感谢你。
此外,作者说如果 Resource 是不可变的,则以下代码是安全的。
@NotThreadSafe
public class UnsafeLazyInitialization {
private static Resource resource;
public static Resource getInstance() {
if (resource == null)
resource = new Resource(); // unsafe publication
return resource;
}
}
第 16.3 节 初始化安全的保证允许正确构造的不可变对象在线程之间安全共享而无需同步,无论它们如何发布,即使使用数据竞争发布。(这意味着
unsafeLazyInitialization
如果它是不可变的,它实际上是安全Resource
的。)
对于本题的第二部分,在另一个问题中详细讨论(点击这里)