为了在线程安全的方式中使用没有最终字段的有效不可变对象,在初始化后使对象可用于其他线程时需要使用安全发布惯用法之一,否则这些线程可以看到处于部分初始化状态的对象(从
Java Concurrency in Practice开始) ):
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.
声明不可变对象的字段作为最终释放此限制(即,它保证如果其他线程看到对该对象的引用,它们也会看到其完全初始化状态的最终字段).但是,在一般情况下,它不保证其他线程一旦发布就可以看到对该对象的引用,因此您可能仍需要使用安全发布来确保它.
请注意,如果对象实现了接口,则可以使用Collections.unmodifiableList()等使用的方法:
class ImmutableFooWrapper implements IFoo {
private final IFoo delegate; // final provides safe publication automatically
public ImmutableFooWrapper(IFoo delegate) {
this.delegate = delegate;
}
...
}
public IFoo immutableFoo(IFoo foo) {
return new ImmutableFooWrapper(foo);
}