为了以
final线程安全的方式使用没有字段的有效不可变对象,在初始化后使对象可用于其他线程时,需要使用一种安全的发布习惯用法,否则这些线程可以看到处于部分初始化状态的对象(来自Java并发在实践中):
- 从静态初始化程序初始化对象引用;
- 将对它的引用存储到volatile字段或AtomicReference中;
- 将对它的引用存储到适当构造的对象的最终字段中;要么
- 将对它的引用存储到由锁适当保护的字段中。
将不可变对象的字段声明为as
final会释放此限制(即,如果其他线程看到对该对象的引用,它们也
final将以完全初始化的状态看到其字段)。但是,通常情况下,它不能保证其他线程可以在对象发布后立即看到对该对象的引用,因此您可能仍需要使用安全发布来确保对该对象的引用。
请注意,如果您的对象实现了接口,则可以使用
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);}


