在 Java Concurrency In Practice 中,作者表示
- 不可变对象(immutable对象)可以通过任何机制发布
- 任何线程都可以安全地使用不可变对象(immutable对象),无需额外同步,即使不使用同步来发布它们。
是否意味着以下成语可以安全地发布不可变对象(immutable对象)?
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添加的列表中的Immutable Object)
非常感谢。
另外,作者说如果 Resource 是不可变的,下面的代码是安全的。
@NotThreadSafe
public class UnsafeLazyInitialization {
private static Resource resource;
public static Resource getInstance() {
if (resource == null)
resource = new Resource(); // unsafe publication
return resource;
}
}
Section16.3 The guarantee of initialization safety allows properly constructed immutable objects to be safely shared across threads without synchronization, regardless of how they are published even if published using a data race. (This means that
unsafeLazyInitialization
is actually safe ifResource
is immutable.)
关于本题的第二部分,在另一个问题中详细讨论(点击here)
最佳答案
是的,你是对的,存在数据竞争。
只有 ImmutableObject
是不可变的并且可以在线程之间安全共享,但是您的 List
没有这些相同的保证,因此添加之间存在数据竞争ImmutableObject
并检索它。
在 JCIP 中,作者的意思是不可变对象(immutable对象)可以安全发布,因为您不必担心制作防御性副本之类的事情。
至于:
Immutable objects can be used safely by any thread without additional synchronization, even when synchronization is not used to publish them.
这个语句意味着给定两个线程,它们都通过任何方式获得了一个不可变对象(immutable对象) A
,它们都可以使用对象 A
而不必担心线程安全问题.
关于Java 并发 - 发布不可变对象(immutable对象)(Java 并发实践),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14617542/