#WeakHashMapjava
HashMap
,內部數組,數組相同hash鏈表,不一樣HashMap
,WeakHashMap
內部鏈表節點繼承弱引用
,並在get
的時候根據弱引用的構造參數隊列,來判斷GC
,同時移除Keyprivate static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> { V value; final int hash; Entry<K,V> next; /** * 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; }
public V get(Object key) { Object k = maskNull(key); int h = hash(k); //得到通過移除key的數組table[] Entry<K,V>[] tab = getTable(); int index = indexFor(h, tab.length); Entry<K,V> e = tab[index]; //相同hash鏈表 遍歷查找相同 while (e != null) { if (e.hash == h && eq(k, e.get())) return e.value; e = e.next; } return null; }
//getTable調用最後到這裏 //弱引用key回收會加入到隊列,由JVM完成 private void expungeStaleEntries() { //遍歷要回收的key for (Object x; (x = queue.poll()) != null; ) { //同步塊,考慮回收時,有Put操做改變table[] 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) //刪除e,鏈表開頭指向回收節點的next 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; } } } }