1 回答

TA貢獻1860條經驗 獲得超9個贊
最近在看《Java 并發編程實戰》,個人的理解:
首先,看里面的 doSomething(e) 方法,這個方法應該是在 ThisEscape 中,不然就無法解釋。也就是說,通過 doSomething(e) 方法可以修改 ThisEscape 中的屬性或者調用 ThisEscape 中的其他方法。
例子中的代碼,在多線程環境下,會出現這樣一種情況:
線程 A 和線程 B 同時訪問 ThisEscape 構造方法,這時線程 A 訪問構造方法還為完成(可以理解為 ThisEscape 為初始化完全),此時由于 this 逸出,導致 this 在 A 和 B 中都具有可見性,線程 B 就可以通過 this 訪問 doSomething(e) 方法,導致修改 ThisEscape 的屬性。也就是在 ThisEscape 還為初始化完成,就被其他線程讀取,導致出現一些奇怪的現象。
這也就是 this 逸出。
通過 《Java 并發編程實戰》 官網的書本 example 源碼包,也證實了 doSomething 的確是 ThisEscape 中的方法。
package net.jcip.examples;
/**
* ThisEscape
* <p/>
* Implicitly allowing the this reference to escape
*
* @author Brian Goetz and Tim Peierls
*/
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 {
}
}

TA貢獻1844條經驗 獲得超8個贊
實話實說多線程、逸出我不是很懂,但是我懂內部類,所以可以來強答一下,內部類、匿名內部類都可以訪問外部類的對象的域,為什么會這樣,實際上是因為內部類構造的時候,會把外部類的對象this隱式的作為一個參數傳遞給內部類的構造方法,這個工作是編譯器做的,他會給你內部類所有的構造方法添加這個參數,所以你例子里的匿名內部類在你構造ThisEscape時就把ThisEscape創建的對象隱式的傳給匿名內部類了。至于這樣會出什么問題我并不明白,貌似是怕onEvent會操作外部類的私有域?這部分需要你來教我了
添加回答
舉報