this引用逸出


  最近在看《Java 並發編程實踐》看到3.2章里面的關於發布和逸出的部分,寫一下心得,算是mark一下,主要是構造過程中this引用的逸出。

書上面給出了一個構造過程中this逸出的例子:

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引用保存到某個地方,只要其他線程不會在構造函數完成之前使用它。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM