假设我有一个班级Publisher
,其中Subscriber
列表中存储了WeakReference<>
个对象
public interface Subscriber {
void update();
}
public class Publisher {
private final List<WeakReference<Subscriber>> subscribers = new CopyOnWriteArrayList<>();
public void subscribe(final Subscriber subscriber) {
subscribers.add(new WeakReference<>(subscriber));
}
public void publish() { ...
在调用Publisher::subscribe
和稍后调用Publisher::publish
之间,弱引用列表中的Subscriber
可能已被垃圾回收,因此我需要检查它是否为{{ 1}}使用之前。
我的问题是,对于null
,下面的代码是否安全可靠?
publish
是否有可能在过滤public void publish() {
//filter out garbage collected items
subscribers = subscribers.stream()
.filter(sub -> sub.get() != null)
.collect(Collectors.toList());
//use the remaing objects
for (final WeakReference<Subscriber> sub : subscribers) {
sub.get().update());
}
}
和调用subscribers
之间垃圾收集器已经破坏了另一个对象?
我应该在更新时进行第二次Subscriber::update
检查吗?
null
答案 0 :(得分:5)
您建议的第二次无效检查也不够好,因为第一次调用get()
可能会返回非空值,第二次调用可能会返回null
。我建议:
for (WeakReference<Subscriber> subRef : subscribers) {
Subscriber sub = subRef.get();
if (sub != null) {
sub.update();
}
}
或者使用Java 8的流(未经测试):
subscribers
.stream()
.map(WeakReference::get)
.filter(s -> s != null)
.forEach(Subscriber::update);