this引用逸出是指,在类的构造方法中发布该类的对象,导致尚未构造完全的对象被其他线程访问。这样一来,不同的线程得到的可能是不同的结果,有些线程访问的是构造完全的对象,而另一些线程则会访问到尚未构造完全的对象,最终导致不可预测的错误。
下面来看2个代码示例。
public class UnSafeDemo{
public UnSafeDemo(EventSource source){
source.registerListener(
new EventListener(){
public void onEvent(Event e){
doSomething(e);
}
}
);
}
}
以上是this引用逸出的例子。一个类的实例化过程中,类的构造方法是最先进行实例化的,如果在构造方法进行对象发布,就会造成对象实例化尚未完成,这个尚未完全的对象就被发布的情况。
如何避免this引用逸出?我们来看下一个代码示例。
public class SafeDemo{
private final EventListener listener;
//在构造方法中先实现业务逻辑,但并不发布
private SafeDemo(){
listener = new EventListener(){
public void onEvent(Event e){
doSomething(e);
}
};
}
//专门用一个公共静态方法发布这个对象
public static SafeDemo getInstance(EventSource source){
SafeDemo safe = new SafeDemo();
source.registerListener(safe.listener);
return safe;
}
}
以上这个例子将业务逻辑实现与发布这2个动作分离开来,避免了尚未实例化完全的对象被发布。