gpt4 book ai didi

java - WeakHashMap 如何在引用放入 ReferenceQueue 后_实际_找到条目

转载 作者:行者123 更新时间:2023-12-04 10:26:31 24 4
gpt4 key购买 nike

一个 WeakHashMapWeakReference 的工作原理差不多再加上一个 ReferenceQueue - 关于这个的消息为零。这是它应该如何工作的精简示例:

public class ReferenceQueuePlayground {

public static void main(String[] args) {
ReferenceQueue<Referent> q = new ReferenceQueue<>();

Referent ref = new Referent();
WeakReference<Referent> weak = new WeakReference<>(ref, q);

ref = null;

// wait for GC to reclaim Referent
while (weak.get() != null) {
System.gc();
}

// this might return null, because ReferenceQueue is notified asynchronously
// but I am assuming the happy path here
Reference<? extends Referent> reference = q.poll();

// this will be false
System.out.println(reference == null);
// this will be true
System.out.println(reference.get() == null);
}

@RequiredArgsConstructor
@Getter
static class Referent {

}
}

这正是 WeakHashMap有效 - 它会在 referent 时收到通知回收和 reference穿上 ReferenceQueue .在一些后续操作中, expungeStaleEntries被调用,它基本上将从这个 ReferenceQueue 中获取元素一一并对其采取行动。

我遇到的问题:如果 referent,它如何“对他们采取行动”现在没了?这是一个 ...HASHMap毕竟,所以为了删除元素,它必须知道它是 hashCode .你怎么知道 hashCode对于现在已经消失的东西?

最佳答案

有两种方法。第一个是线性搜索。

由于所指对象确实消失了,您无法计算 hashCode在上面,您可以搜索Reference== ,跨越 Map 中的所有条目.在发布的示例中,您可以添加几行,例如:

    WeakReference<Referent> weak = new WeakReference<>(ref, q);
// <--- this
System.out.println(weak);

ref = null;

while (weak.get() != null) {
System.out.println("not yet");
System.gc();
}

Reference<? extends Referent> reference = q.poll();
// <---- and this
System.out.println(reference);

这些都将打印相同的东西,这是完全有道理的。所以理论上,一个 WeakHashMap可以拿 reference它得到(实际上是 Entry )并遍历其内部数组,直到找到匹配项。

显然,这会很慢。

第二种方法是 WeakHashMap实际上需要。当 Entry首先创建,它计算 hashCode并将其放入本地字段:
/**
* Creates new entry.
*/
Entry(Object key, V value,
ReferenceQueue<Object> queue,
int hash, Entry<K,V> next) {
super(key, queue);
this.value = value;
this.hash = hash;
this.next = next;
}

此时它知道 Key ,所以它可以计算 hashCode .当 expungeStaleEntries后来被称为:
 private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null; ) {
synchronized (queue) {
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) x;
int i = indexFor(e.hash, table.length);

它已经知道 hashCode ,因为它是在此之前计算的。它不知道 Key ,但也没有必要。

这将有助于找到此 Entry 所在的存储桶,但要实际找到特定的 Entry,它只能使用 ==在条目本身上。自 Key不见了, equals是不可能的,但这没关系。

关于java - WeakHashMap 如何在引用放入 ReferenceQueue 后_实际_找到条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60621660/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com