JAVA并发编程笔记(3)

Publication and Escape

发布一个对象意味着能够从它能够从它当前范围之外被访问到。比如,保存可以被其他代码找到的这个对象的一个引用,或者将其作为一个非私有方法的返回值,或者将其作为参数传递给其它的类。

public static Set<Secret> knownSecrets;

public void initialize() {
knownSecrets = new HashSet<Secret>();
}

这个knownSecrets就被发布了,并且,knownSecrets里面添加的所有secret也都被发布出去了。

class UnsafeStates {
private String[] states = new String[] {
"AK", "AL" ...
};
public String[] getStates() { return states; }
}

这个states就被发布了,而且带来的问题是任何调用者都能够修改里面的内容,这样,很不安全。

public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
看明白这个ThisEscape为什么被发布了么?因为它发布了EventListener,而内部类会带有一个隐式的对外部类的引用。

另外,上面这个类的一个严重问题是,在构造方法中this引用escape了。这也就意味着这个对象在被发布的时候还处于一个不完整的状态。一个常见的情形就是在类的构造方法中启动一个线程。When an object creates a thread from its constructor, it almost always shares its this reference with the new thread, either explicitly (by passing it to the constructor) or implicitly (because the Thread or Runnable is an inner class of the owning object). 当然这本身没什么问题,但最好不要在构造方法中就启动这个线程,而是把Thread.start()放到一个单独的init方法中供其它对象调用。

要避免不完全构造的问题,可以采用下面的方式:

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;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值