特性
WeakHashMap自身特点是,当除了自身有key的引用外,在别的地方没有引用,gc垃圾回收后,WeakHashMap在进项增删改查操作时会自动删除这些key,节省了内从空间。 WeakHashMap适合做缓存系统。
实现原理
WeakHashMap的键值对Entry继承自WeakReference,并实现了Map.Entry
Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>
Entry(Object key, V value,
ReferenceQueue<Object> queue,
int hash, Entry<K,V> next) {
//对key对象做弱引用,同时传入引用队列
super(key, queue);
this.value = value;
this.hash = hash;
this.next = next;
}
entry是key对象的弱引用持有者,当key对象被GC清理之后,该对象会被放到Referencequeue中,即文中的queue,当下次操作该map时候,会同步触发调用expungeStaleEntries函数,自动移除map中相应的entry。
/**
* Expunges stale entries from the table.
*/
private void expungeStaleEntries() {
//循环处理queue中的对象
for (Object x; (x = queue.poll()) != null; ) {
//对queue对象加锁并删除对象
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;
}
}
}
}
WeakHashMap的增删改查操作都会直接或者间接的调用expungeStaleEntries()方法,达到及时清除过期entry的目的。
此特性会导致两次调用size、get等方法可能会返回不一致的数据。