为了账号安全,请及时绑定邮箱和手机立即绑定

java如何理解隐式地使this引用逸出

java如何理解隐式地使this引用逸出

MYYA 2019-05-25 15:54:28
这是《Java并发编程实战》3.2发布与逸出一节中的示例代码。我无法理解,this是怎么逸出的。//隐式地使this引用逸出(不要这么做)publicclassThisEscape{publicThisEscape(EventSourcesource){source.registerListener(newEventListener(){publicvoidonEvent(Evente){doSomething(e);}});}}书上说,当ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身,因为在这个内部类的实例中包含了对ThisEscape实例的隐含引用。
查看完整描述

2 回答

?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

最近在看《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中的方法。
packagenet.jcip.examples;
/**
*ThisEscape
*

*Implicitlyallowingthethisreferencetoescape
*
*@authorBrianGoetzandTimPeierls
*/
publicclassThisEscape{
publicThisEscape(EventSourcesource){
source.registerListener(newEventListener(){
publicvoidonEvent(Evente){
doSomething(e);
}
});
}
voiddoSomething(Evente){
}
interfaceEventSource{
voidregisterListener(EventListenere);
}
interfaceEventListener{
voidonEvent(Evente);
}
interfaceEvent{
}
}
JavaConcurrencyinPractice
                            
查看完整回答
反对 回复 2019-05-25
?
翻阅古今

TA贡献1780条经验 获得超5个赞

实话实说多线程、逸出我不是很懂,但是我懂内部类,所以可以来强答一下,内部类、匿名内部类都可以访问外部类的对象的域,为什么会这样,实际上是因为内部类构造的时候,会把外部类的对象this隐式的作为一个参数传递给内部类的构造方法,这个工作是编译器做的,他会给你内部类所有的构造方法添加这个参数,所以你例子里的匿名内部类在你构造ThisEscape时就把ThisEscape创建的对象隐式的传给匿名内部类了。至于这样会出什么问题我并不明白,貌似是怕onEvent会操作外部类的私有域?这部分需要你来教我了
                            
查看完整回答
反对 回复 2019-05-25
  • 2 回答
  • 0 关注
  • 778 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信