3.2 发布与逸出

“发布(Publish)”一个对象的意思是指,使对象能够在当前作用域之外的代码中使用。例如,将一个指向该对象的引用保存到其他代码可以访问的地方,或者在某一个非私有的方法中返回该引用,或者将引用传递到其他类的方法中。在许多情况中,我们要确保对象及其内部状态不被发布。而在某些情况下,我们又需要发布某个对象,但如果在发布时要确保线程安全性,则可能需要同步。发布内部状态可能会破坏封装性,并使得程序难以维持不变性条件。例如,如果在对象构造完成之前就发布该对象,就会破坏线程安全性。当某个不应该发布的对象被发布时,这种情况就被称为逸出(Escape)。3.5节介绍了如何安全发布对象的一些方法。现在,我们首先来看看一个对象是如何逸出的。

发布对象的最简单方法是将对象的引用保存到一个公有的静态变量中,以便任何类和线程都能看见该对象,如程序清单3-5所示。在initialize方法中实例化一个新的HashSet对象,并将对象的引用保存到knownSecrets中以发布该对象。

程序清单3-5 发布一个对象

public static Set<Secret>knownSecrets;

public void initialize(){

knownSecrets=new HashSet<Secret>();

}

当发布某个对象时,可能会间接地发布其他对象。如果将一个Secret对象添加到集合knownSecrets中,那么同样会发布这个对象,因为任何代码都可以遍历这个集合,并获得对这个新Secret对象的引用。同样,如果从非私有方法中返回一个引用,那么同样会发布返回的对象。程序清单3-6中的UnsafeStates发布了本应为私有的状态数组。

程序清单3-6 使内部的可变状态逸出(不要这么做) ...

Get Java并发编程实战 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.