Java并发编程实践笔记之—发布和逸出(Publication and Escape)
2015-01-28 20:58
549 查看
什么是发布对象——使对象在当前作用域之外的代码中使用
什么是逸出——当某个不应该发布的对象被发布时
当发布某个对象时,可能会间接地发布其他对象。如果将一个对象添加到被发布的集合对象中,那么同样会发布这个对象
当发布一个对象时,在该对象的非私有域中引用的所有对象同样会被发布;或者说当把一个对象传递给某个外部方法时,就相当于发布了这个对象
不安全的对象构造过程:指this引用在构造函数中逸出
常见的错误做法1是,在构造函数中启动一个线程,this引用就被新创建的线程共享了
常见的错误做法2是,在构造函数中注册一个事件监听器,this引用就被触发被监听事件的线程共享了
解决办法是:使用一个私有的构造函数和一个公共的工厂方法,看下面的例子
注意:只有当对象的构造函数返回时,对象才处于可预测和一致的状态。因此,当从对象的构造函数中发布对象时,只是发布了一个尚未构造完成的对象,即使发布对象的语句在最后一行也是如此,如果this在构造过程中逸出,那么这种对象就被认为是不正确的构造
什么是逸出——当某个不应该发布的对象被发布时
对象如何逸出的
最简单的方法是将对象的引用保存到一个公有的静态变量中当发布某个对象时,可能会间接地发布其他对象。如果将一个对象添加到被发布的集合对象中,那么同样会发布这个对象
当发布一个对象时,在该对象的非私有域中引用的所有对象同样会被发布;或者说当把一个对象传递给某个外部方法时,就相当于发布了这个对象
不安全的对象构造过程:指this引用在构造函数中逸出
常见的错误做法1是,在构造函数中启动一个线程,this引用就被新创建的线程共享了
常见的错误做法2是,在构造函数中注册一个事件监听器,this引用就被触发被监听事件的线程共享了
解决办法是:使用一个私有的构造函数和一个公共的工厂方法,看下面的例子
public class SafeListener { private final EventListener listener; private SafeListener() { listener = new EventListener() { public void onEvent(Event e) { doSomething(e); } }; } public static SafeListener newInstance(EventSource source) { //只有当构造函数返回时,this引用才应该从线程中逸出 SafeListener safe = new SafeListener(); source.registerListener(safe.listener); return safe; } }
注意:只有当对象的构造函数返回时,对象才处于可预测和一致的状态。因此,当从对象的构造函数中发布对象时,只是发布了一个尚未构造完成的对象,即使发布对象的语句在最后一行也是如此,如果this在构造过程中逸出,那么这种对象就被认为是不正确的构造
相关文章推荐
- Java并发编程实践笔记之—阻塞和中断方法(Blocking and Interruptible Methods)
- JAVA并发编程学习笔记------对象的可见性及发布逸出
- Java并发编程实践笔记(五)——chapter3(发布溢出,线程封闭)
- Java并发编程学习笔记之发布逸出
- java并发编程实践之安全发布和逸出
- java并发编程实践之安全发布和逸出
- 编程实践笔记{Java 线程 并发处理 Webservice}
- java并发编程实践笔记
- JAVA 并发编程实践 - 原子变量与非阻塞同步机制 笔记
- java并发编程实践笔记
- Java并发编程实践笔记之—线程
- Java并发编程实践笔记之—线程封闭(Thread Confinement)
- java并发编程实践学习笔记
- java并发编程实践笔记
- java并发编程实践笔记
- Java并发编程实践笔记之——原子性(Atomicity)
- java并发编程实践笔记
- java并发编程实践笔记
- Java并发编程实践笔记之—并发容器(Concurrent Collections)
- java并发编程实践笔记