Java集合-WeakHashMap

345 阅读1分钟

特性

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等方法可能会返回不一致的数据。