逸出 java_【java】知识系谱-基础篇-线程-发布、逸出
java并發(fā)編程實(shí)戰(zhàn)的解釋,不夠詳細(xì),尤其this引用逸出讓人理解有些費(fèi)解,java并發(fā)編程實(shí)戰(zhàn)里面的內(nèi)容就直接拷貝過(guò)來(lái)
發(fā)布:使對(duì)象能夠在當(dāng)前作用域之外的代碼中使用
逸出:當(dāng)某個(gè)不該被發(fā)布的對(duì)象被發(fā)布時(shí),這種情況稱(chēng)為逸出
發(fā)布內(nèi)部狀態(tài)將會(huì)破壞封裝性,并使得程序難以維持不變性條件
當(dāng)某個(gè)對(duì)象逸出后,必須對(duì)程序進(jìn)行分析,以便找出哪些對(duì)象或線程可能會(huì)誤用該對(duì)象,這正是使用封裝的最主要原因:使對(duì)程序的正確性分析變?yōu)榭赡?#xff0c;并使無(wú)意中破壞設(shè)計(jì)約束條件變得更難
無(wú)論其它的線程會(huì)對(duì)逸出的對(duì)象引用執(zhí)行何種操作,都不重要,因?yàn)檎`用該引用的風(fēng)險(xiǎn)始終是客觀存在的
發(fā)布的實(shí)現(xiàn)方式
1.對(duì)象引用作為非私有屬性
代碼示例:
//只是代碼示例,不推薦這樣初始化List
public class test {
public List animals = new ArrayList(){{
add(new Animal());
}};
}
List對(duì)象和List中的Animal對(duì)象都被發(fā)布出去。
2.對(duì)象引用被非私有方法返回
代碼示例:
//只是代碼示例,不推薦這樣初始化List
public class test {
private List animals = new ArrayList(){{
add(new Animal());
}};
public List getAnimals(){
return animals;
}
}
1、2的一樣,List對(duì)象和List中的Animal對(duì)象發(fā)布出去。只是一個(gè)是方法發(fā)布出去,一個(gè)是屬性發(fā)布出去。
3.外部方法發(fā)布對(duì)象
外部方法定義:
對(duì)當(dāng)前類(lèi)來(lái)說(shuō),外部方法是指行為不完全由當(dāng)前類(lèi)來(lái)規(guī)定的方法,包括其他類(lèi)中定義的方法以及當(dāng)前類(lèi)中可以被改寫(xiě)的方法(既不是私有方法,也不是final方法)
代碼示例:
public class test {
public void setAnimals(Animal animal){
animal.setDag(
new Dog(){
public void doSomething(){
...
};
}
)
}
}
當(dāng)前類(lèi)test來(lái)說(shuō),setDag為外部方法,Dog就被發(fā)布了。
this引用逸出
基于外部方法發(fā)布對(duì)象引出this引用逸出問(wèn)題。直接拿java并發(fā)編程實(shí)戰(zhàn)的代碼
public class ThisEscape {
public ThisEscape(EventSource source){
source.registerListener(
new EventListener(){
public void onEvent(Event e){
doSomething(e)
}
});
}
}
java并發(fā)編程實(shí)戰(zhàn)的解釋:
當(dāng)ThisEscape發(fā)布EventListener時(shí),它也無(wú)條件地發(fā)布了封裝(enclosing)ThisEscape的實(shí)例,因?yàn)閮?nèi)引類(lèi)(inner class inst ances)的實(shí)例包含了對(duì)封裝實(shí)例隱含的引用。
這里發(fā)布new EventListener()內(nèi)部對(duì)象,隱式的有個(gè)this。也就是ThisEscape也會(huì)被發(fā)布出去,但是ThisEscape還沒(méi)有構(gòu)建完成,存在逸出的可能,ThisEscape在未構(gòu)建完成被發(fā)布了。怎么處理這個(gè)可能逸出的問(wèn)題,就是讓ThisEscape構(gòu)建完成再發(fā)布出去就可以了。java并發(fā)編程實(shí)戰(zhàn)的提到私有構(gòu)造函數(shù)+公共的工廠方法解決可能逸出的問(wèn)題。
public class ThisEscape {
private final EventListener listener;
private ThisEscape(){
listener = new EventListener(){
public void onEvent(Event e){
doSomething(e)
}
};
}
public static ThisEscape newInstance(EventSource source){
ThisEscape thisEscape = new ThisEscape();
source.registerListener(thisEscape.listener);
return thisEscape;
}
}
同理在構(gòu)造函數(shù)可以新建線程,當(dāng)不要start()。start()的話(huà)this被新線程共享。下面代碼就是錯(cuò)誤的:
public class ThisEscape {
private Thread thread;
public ThisEscape(){
thread = new Thread(){
public void run(){
...
}
};
thread.start(); //可以在構(gòu)造函數(shù)中new Thread 但是不要start
}
public static void main(String[] args){
ThisEscape a = new ThisEscape();
}
}
總結(jié)
以上是生活随笔為你收集整理的逸出 java_【java】知识系谱-基础篇-线程-发布、逸出的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 备案后退房后再买算首套吗(备案后退房)
- 下一篇: 安卓定时器(安卓 定时器)
