1 回答

TA貢獻(xiàn)1860條經(jīng)驗(yàn) 獲得超9個(gè)贊
最近在看《Java 并發(fā)編程實(shí)戰(zhàn)》,個(gè)人的理解:
首先,看里面的 doSomething(e) 方法,這個(gè)方法應(yīng)該是在 ThisEscape 中,不然就無法解釋。也就是說,通過 doSomething(e) 方法可以修改 ThisEscape 中的屬性或者調(diào)用 ThisEscape 中的其他方法。
例子中的代碼,在多線程環(huán)境下,會(huì)出現(xiàn)這樣一種情況:
線程 A 和線程 B 同時(shí)訪問 ThisEscape 構(gòu)造方法,這時(shí)線程 A 訪問構(gòu)造方法還為完成(可以理解為 ThisEscape 為初始化完全),此時(shí)由于 this 逸出,導(dǎo)致 this 在 A 和 B 中都具有可見性,線程 B 就可以通過 this 訪問 doSomething(e) 方法,導(dǎo)致修改 ThisEscape 的屬性。也就是在 ThisEscape 還為初始化完成,就被其他線程讀取,導(dǎo)致出現(xiàn)一些奇怪的現(xiàn)象。
這也就是 this 逸出。
通過 《Java 并發(fā)編程實(shí)戰(zhàn)》 官網(wǎng)的書本 example 源碼包,也證實(shí)了 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貢獻(xiàn)1844條經(jīng)驗(yàn) 獲得超8個(gè)贊
實(shí)話實(shí)說多線程、逸出我不是很懂,但是我懂內(nèi)部類,所以可以來強(qiáng)答一下,內(nèi)部類、匿名內(nèi)部類都可以訪問外部類的對(duì)象的域,為什么會(huì)這樣,實(shí)際上是因?yàn)閮?nèi)部類構(gòu)造的時(shí)候,會(huì)把外部類的對(duì)象this隱式的作為一個(gè)參數(shù)傳遞給內(nèi)部類的構(gòu)造方法,這個(gè)工作是編譯器做的,他會(huì)給你內(nèi)部類所有的構(gòu)造方法添加這個(gè)參數(shù),所以你例子里的匿名內(nèi)部類在你構(gòu)造ThisEscape時(shí)就把ThisEscape創(chuàng)建的對(duì)象隱式的傳給匿名內(nèi)部類了。至于這樣會(huì)出什么問題我并不明白,貌似是怕onEvent會(huì)操作外部類的私有域?這部分需要你來教我了
添加回答
舉報(bào)