转自:http://blog.csdn.net/joker_zhou/article/details/7322801
(1)发布:发布是指将一个对象,使其引用储存到一个其他代码可以访问到的地方,在一个非私有方法返回这个引用,也可以把它传递到其他对象中.
a) 发布最简单的就是将对象设置到公共静态域中
b) 发布第二种简单的方式就是在一个公共方法内直接return 对象的引用
第三种的发布就很隐秘了.就是讲自身的对象引用发布到另一个对象的引用中.
可能在构造中出现如此这就是this例如:
这样 source就持有ThisEscape的内部类EvenListener()而Evenlistener可能会带出ThisEscape中的保护数据引用,可以使用工厂和私有构造防止发布逸出,这样ThisEscape对象就可以构造完成然后使用ThisEscape.registerListener(source)放入监听器.最好不要在构造内注册监听器或者启动线程.而在工厂内初始化这些事情.
class A1{ public EventListener l; } public class MyThread{ EventListener l=null; private MyThread(){ l=new EventListener() { }; } public static MyThread newInstance(A1 a){ MyThread my=new MyThread(); <span style="white-space:pre"> </span> a.l=my.l; return my; } }
其实A1中的l我没有封装.应该加以封装.我只是掩饰下如何注册
(2)逸出:如果对象在没有构造完成前就将其发布,这就是逸出.在构造中启动线程,会使未构造完成的对象发布出去,造成逸出.
(3)如何安全的发布:
a) 通常发布线程与消费线程需要同步化.
b) 通过静态初始化初始对象的引用.
c) 引用储存到volatile或者AtomicReference
d) 引用储存到正确创建对象的final域中
(4)如果需要发布一个非线程安全的状态集(就是包含基本类型的对象),可以先复制对象,然后发布复制后的对象.这样避免外来客户修改非线程安全的类.造成同步错误.这前提是不需要此集合状态在多个线程间一致.
(5)发布一个线程安全的类,并不需要复制-发布.
(6)可以安全的发布一个线程安全的类并且发布时不需要有任何我约束行为