Java 安全使用WeakReference
假设我有一个类Java 安全使用WeakReference,java,garbage-collection,weak-references,Java,Garbage Collection,Weak References,假设我有一个类Publisher,其中有一个Subscriber对象列表,存储在WeakReference 在筛选Subscriber和调用Subscriber::update之间,垃圾收集器是否可能破坏了另一个对象? 更新时是否应该进行第二次null检查 for (final WeakReference<Subscriber> sub : subscribers) { if (sub.get() != null) { sub.get(
Publisher
,其中有一个Subscriber
对象列表,存储在WeakReference
在筛选Subscriber
和调用Subscriber::update
之间,垃圾收集器是否可能破坏了另一个对象?
更新时是否应该进行第二次null
检查
for (final WeakReference<Subscriber> sub : subscribers) {
if (sub.get() != null) {
sub.get().update());
}
}
for(最终WeakReference sub:subscribers){
if(sub.get()!=null){
sub.get().update());
}
}
您建议的第二次空值检查也不够好,因为对get()
的第一次调用可能返回非空值,而第二次调用可能返回null
。我建议:
for (WeakReference<Subscriber> subRef : subscribers) {
Subscriber sub = subRef.get();
if (sub != null) {
sub.update();
}
}
因此,如果我理解正确,GC可以在执行过程中的任何一行执行清理?@flkes:是的,如果没有其他东西使它保持活动状态。GC不能在
get()
之后立即销毁对象,而get()
返回的强引用在范围内。@AlexCohn:我不太清楚你在说什么,但关键是,在OP的代码中,他们调用get()
并检查结果是否为null,但随后再次调用get()
,并且不能保证在该点上仍然为非null。是的,如果(sub.get()!=null){sub.get().update();}模式不好。
for (final WeakReference<Subscriber> sub : subscribers) {
if (sub.get() != null) {
sub.get().update());
}
}
for (WeakReference<Subscriber> subRef : subscribers) {
Subscriber sub = subRef.get();
if (sub != null) {
sub.update();
}
}
subscribers
.stream()
.map(WeakReference::get)
.filter(s -> s != null)
.forEach(Subscriber::update);