发布(Publish)一个对象是指使对象能够在当前作用域之外的代码中被使用。例如将指向该对象的引用保存到其他代码可以访问到的地方 ,或者在一个非私有的方法中返回一个对象的引用或者将该引用传递到其他类的方法中。当发布一个对象时,在该对象的非私有域中的引用同样被发布出去,一般来说如果一个已经发布的对象能够通过非私有的变量和方法调用到其他的对象那么这个对象也被发布。
逸出(Escape)是指 一个比应该被发布的对象被发布出去。
在 《Java Concurrency in Practice》中关于隐式使用This 引用逸出的示例,比较难以理解如何逸出。ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身,因为在这个内部类的实例中包含了对ThisEscape 实例的隐含引用。这个个人的理解代码是:
/** * * @author zhangwei_david * @version $Id: ThisEscape.java, v 0.1 2014年11月3日 上午9:37:54 zhangwei_david Exp $ */ public class ThisEscape { private String name = null; public ThisEscape(EventSource source) { source.registerListener(new EventListener() { public void onEvent(Event event) { doSomething(event); } }); name = "TEST"; } /** * * @param event */ protected void doSomething(Event event) { System.out.println(name.toString()); } } import java.awt.Event; /** * * @author zhangwei_david * @version $Id: Listener.java, v 0.1 2014年11月3日 上午9:40:13 zhangwei_david Exp $ */ public interface EventListener { public void onEvent(Event event); }
/** * * @author zhangwei_david * @version $Id: EventSource.java, v 0.1 2014年11月3日 上午9:38:40 zhangwei_david Exp $ */ public class EventSource { public void registerListener(EventListener listener) { listener.onEvent(null); } }
/** * * @author zhangwei_david * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $ */ public class Client { /** * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { EventSource es = new EventSource(); new ThisEscape(es); } }
运行的结果是:
Exception in thread "main" java.lang.NullPointerException at com.cathy.demo.concurrency.escape.ThisEscape.doSomething(ThisEscape.java:33) at com.cathy.demo.concurrency.escape.ThisEscape$1.onEvent(ThisEscape.java:21) at com.cathy.demo.concurrency.escape.EventSource.registerListener(EventSource.java:15) at com.cathy.demo.concurrency.escape.ThisEscape.<init>(ThisEscape.java:18) at com.cathy.demo.concurrency.escape.Client.main(Client.java:21)
这个就是由于在name 初始化之前,就使用了ThisEscape实例,而此时实例尚未完成初始化。
同样修改SafeListener
import java.awt.Event; /** * * @author zhangwei_david * @version $Id: SafeListener.java, v 0.1 2014年11月3日 上午10:20:26 zhangwei_david Exp $ */ public class SafeListener { private final EventListener listener; private String name = null; private SafeListener() { listener = new EventListener() { public void onEvent(Event event) { doSomething(); } }; name = "TEST"; } public static SafeListener newInstance(EventSource eventSource) { SafeListener safeListener = new SafeListener(); eventSource.registerListener(safeListener.listener); return safeListener; } /** * */ protected void doSomething() { System.out.println(name.toString()); } } /** * * @author zhangwei_david * @version $Id: Client.java, v 0.1 2014年11月3日 上午9:45:48 zhangwei_david Exp $ */ public class Client { /** * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { EventSource es = new EventSource(); // new ThisEscape(es); SafeListener.newInstance(es); } }
结果是:
TEST
相关推荐
体系结构 经典KWIC问题 隐式调用风格 实现上没有使用Java自带的观察者,自身实现了较为简单的EventManager 附带逻辑视图、开发视图
显式和隐式、过滤器intent的使用,欢迎有需要的朋友下载!
一维热传导方程的MATLAB计算,使用隐式差分格式,追赶法计算
在VC6.0中,隐式调用DLL例子。 在VC6.0中,隐式调用DLL例子。 在VC6.0中,隐式调用DLL例子。
使用隐式Intent,创建一个启动器应用来替换Android默认的启动器应用
在JavaScript中,this 的概念比较复杂。除了在面向对象编程中,this 还是随处可用的。这篇文章介绍了this的隐式绑定,希望大家能够喜欢。
整理了一下关于mysql的前因后果,以及如何避免隐式提交
用于推荐方法研究或数据挖掘的,隐式反馈数据集。
matlab实现隐式QR算法,其中包括了双重步位移的QR迭代算法
Android中使用隐式方式打开一个新的Activity!
abaqus显示和隐式算法的差别.pdf
这是通过隐式意图调用安卓系统的各个功能,比如通过隐式意图进入无线网络设置界面,等等。至于最基本的,在intent-filter 里设置启动条件,这里没有给出。
隐式意图跳转Activity
了解JSP 隐式对象的分类和组成 能够运用隐式对象进行JSP 编程 理解Page、Request、Session 和Application 范围的区别
EL表达式,介绍EL表达的基本原理,详细的讲解了内置参数。
authorware隐式菜单的制作 有源码学习
activity显式隐式跳转,提供显式隐式跳转方式代码
LS-DYNA显示和隐式求解步骤,一步步教你怎么做,十分详细
C语言隐式类型转换规则。了解一下对写程序有好处,可以防止不必要的错误
网格相关,隐式表面,卷积表面论文整合,光滑血管的重建方法,课程资料、网格计算资料,隐式表面双线性表示