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