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);