概念
- 發(fā)布一個對象(publish):
使對象能夠在當(dāng)前作用域范圍之外的代碼中使用; - 逸出(escape):
當(dāng)某個不應(yīng)該發(fā)布的對象被發(fā)布出去的情況;
發(fā)布對象的兩種方法:
- 將對象的引用保存到一個公有的靜態(tài)變量中,以便于任何類和線程都能夠看見該對象;
舉例
public class Set<Secret> KnowSecrets;
public void initialize()
{
knownSecrets = new HashSet<Secret>();
}
- 發(fā)布一個內(nèi)部的類實例;
舉例
public class ThisEscape
{
public ThisEscape(EventSource source)
{
source.registerListener(
{
new EventListener()
{
public void onEvent(Event e)
{
doSomething(e);
}
}
});
}
}
發(fā)布某對象的影響:
- 發(fā)布某對象,可能會間接地發(fā)布其他對象;
如上述第一個程序中,如果將一個Sectet對象添加到集合knownSecrets中,那么同樣會發(fā)布這個對象,因為任何代碼都可以訪問該集合(由于是public,公有的),并獲得對這個新Secret對象的引用。 - 發(fā)布某對象時,該對象的非私有域中引用的所有對象同樣會被發(fā)布;
一般來說,如果一個已經(jīng)發(fā)布的對象能夠通過非私有的變量引用和方法調(diào)用到達(dá)其他的對象,那么這些對象也都會被發(fā)布。
外部方法(Alien Method):
假設(shè)一個類A,則行為并不完全由類A來規(guī)定的方法,包括其他類中的定義的方法以及類A中可以被改寫的方法(既不是private方法也不是final方法),則這些方法就稱作為外部方法。
安全的構(gòu)造函數(shù)過程
- 不要再構(gòu)造過程中使用this引用逸出,那何時使用this引用逸出?
只有當(dāng)構(gòu)造函數(shù)返回時,this引用才應(yīng)該從線程中逸出,構(gòu)造函數(shù)可將this引用保存到某地方,只要其他線程在構(gòu)造函數(shù)完成前不使用它即可。 - this應(yīng)用逸出的錯誤操作
在構(gòu)造函數(shù)中啟動一個線程。(在構(gòu)造函數(shù)中創(chuàng)建線程并沒有錯誤,但是最好不要立即啟動它,而是通過start或者initialize方法來啟動); - 如何在構(gòu)造函數(shù)中注冊一個事件監(jiān)聽器或者啟動線程?
使用一個私有的構(gòu)造函數(shù)和一個公共的工廠方法。
舉例:使用工廠方法來防止this引用在構(gòu)造函數(shù)過程中逸出
public class SafeListener {
private final EventListener listener;
>
private SafeListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
};
}
public static SafeListener newInstance(EventSource source) {
SafeListener safe = new SafeListener();
source.registerListener(safe.listener);
return safe;
}
}
[source:Java并發(fā)編程實戰(zhàn)]