this 引用逸出

来源:互联网 发布:中国ntp时间服务器端口 编辑:程序博客网 时间:2024/06/02 13:49

《Java 并发编程实践》 3.2章 发布和逸出的部分:
逸出 : 在不该发布的时候发布了一个引用;
发布:发布对象指 对象的引用在当前作用域之外的代码中使用;

public class ThisEscape {  public ThisEscape(EventSource source) {    source.registerListener(new EventListener() {      public void onEvent(Event e) {        doSomething(e);      }    });  }  void doSomething(Event e) {  }  interface EventSource {    void registerListener(EventListener e);  }  interface EventListener {    void onEvent(Event e);  }  interface Event {  }}

这将导致this逸出,在这个例子里面,当我们实例化ThisEscape对象时,会调用source的registerListener方法,这时便启动了一个线程,而且这个线程持有了ThisEscape对象(调用了对象的doSomething方法),但此时ThisEscape对象却没有实例化完成(还没有返回一个引用),所以我们说,此时造成了一个this引用逸出,即还没有完成的实例化ThisEscape对象的动作,却已经暴露了对象的引用。其他线程访问还没有构造好的对象,可能会造成意料不到的问题。

最后,书里面给出了正确构造过程:

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) {    SafeListener safe = new SafeListener();    source.registerListener(safe.listener);    return safe;  }  void doSomething(Event e) {  }  interface EventSource {    void registerListener(EventListener e);  }  interface EventListener {    void onEvent(Event e);  }  interface Event {  } }

在这个构造中,我们看到的最大的一个区别就是:当构造好了SafeListener对象(通过构造器构造)之后,我们才启动了监听线程,也就确保了SafeListener对象是构造完成之后再使用的SafeListener对象。

对于这样的技术,书里面也有这样的注释:

具体来说,只有当构造函数返回时,this引用才应该从线程中逸出。构造函数可以将this引用保存到某个地方,只要其他线程不会在构造函数完成之前使用它

转载:
this引用逸出
http://www.cnblogs.com/whatisjava/archive/2013/05/29/3106336.html

0 0
原创粉丝点击