private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
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;
}
Entry
的构造方法中,通过调用父类WeakReference
的构造方法,绑定key
和queue
。
当key
被GC回收掉之后,请问queue
中存放的是指向key
的弱引用么?
如果是的话
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);
Entry<K,V> prev = table[i];
Entry<K,V> p = prev;
while (p != null) {
Entry<K,V> next = p.next;
if (p == e) {
if (prev == e)
table[i] = next;
else
prev.next = next;
// Must not null out e.next;
// stale entries may be in use by a HashIterator
e.value = null; // Help GC
size--;
break;
}
prev = p;
p = next;
}
}
}
}
expungeStaleEntries
方法中,从queue
中poll
出来的东西,为什么可以强制类型转换成Entry
?
实际上queue
中存放的是key
所对应的Entry
吗?
看了几遍源码也没有看到有这样的一个过程,求解答,谢谢。
LZ可参看Reference.tryHandlePending
queue中的对象都是Reference实例,也就是Entry对象。
需要说明的是,Reference类有个全局变量的pending属性(也是Reference类型)和一个private变量discovered。纵观全文没有地方对pending赋值,查看文档说明,这个属性就是等待入队的列表。JVM在GC过程中会把即将回收的Reference赋值给pending,通过另一个属性discovered,把即将enqueue的Reference对象链接起来。
很容易看到入队的是Reference实例,也就是Entry
WeakHashMap的Entry‘弱键’就是referent,当弱键GC回收,将会把此reference对象加入到referenceQueue中,对于外部程序,可以通过操作queue来做相应的处理。