安全发布

发布与逸出

发布(Publish)”一个对象的意思是指:使对象能够在当前作用域之外的代码中使用当某个不应该发布的对象被发布时,这种情况就被称为逸出。

安全的对象构造过程

当且仅当对象的构造函数返回时,对象才处于可预测的和一致的状态。因此,当从对象的构造函数中发布对象时,只是发布了一个尚未构造完成的对象,即使发布对象的语句位于构造函数的最后一行也是如此。

不可变对象与初始化安全性

任何线程都可以在不需要额外同步的情况下安全地访问不可变对象,即使在发布这些对象时没有使用同步。

  • 这种保证还将延伸到被正确创建对象中所有 final 类型的域。在没有额外同步的情况下,也可以安全地访问 final 类型的域。

  • 然而,如果 final 类型的域所指向的是可变对象,那么在访问这些所指向的对象的状态时仍然需要同步。

安全发布的常用模式

要安全地发布一个对象,对象的引用以及对象的状态必须同时对其他线程可见

一个正确构造的对象可以通过以下方式来安全地发布:

  • 在静态初始化函数中初始化一个对象引用

  • 将对象的引用保存到 volatile 类型的域,或者 AtomicReference 对象中

  • 将对象的引用保存到某个正确构造对象的 final 类型域中

  • 将对象的引用保存到一个由锁保护的域中

所有的安全发布机制都能确保,当对象的引用对所有访问该对象的线程可见时,对象发布时的状态对于所有线程也将是可见的。

对象的发布需求取决于它的可变性:

  • 不可变对象可以通过任意机制来发布

  • 事实不可变对象必须通过安全发布方式来发布

  • 可变对象必须通过安全发布方式来发布,并且必须是线程安全的或者由某个锁保护起来

最后更新于