weakHashMap解析

weakHashMap

包路径:package java.util;

               import java.lang.ref.WeakReference;

               import java.lang.ref.ReferenceQueue;

public class WeakHashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V> 

1、继承于AbstractMap,实现了Map接口。

2、weakHashMap是哈希表,但是它的键是“弱键”,weakHashMap中保护几个重要的成员变量:

    table是一个Entry[ ]类型的数组,而Entry是一个单向链表,哈希表中的键值对都是存储在Entry数组中的。

   size是表示保存的键值对的数量大小。

   threshold是阈值,用于判断是否需要扩充容量。

   loadFactor是加载因子。

  modCount是用来实现fail-fast机制的。

  queue保存的是“已被GC清除的”“弱引用的键”。

3、该集合类的主要特点是:

随着时间的推移,键值对会逐渐的减少----->GC 垃圾回收

基本原理:weakHashMap的特点是:当除了自身有对key的引用之外,此key没有其他的引用,那么weakHashMap会在下一次对weakHashMap进行增删改查操作的时候及时丢弃该键值对,节约内存的使用,此特性使得weakHashMap比较适合构建缓存系统。

weakHashMap主要是通过expungeStaleEntries函数来实现移除内部不用的Entry从而达到自动释放内部的目的。

 private void expungeStaleEntries() { 
        for (Object x; (x = queue.poll()) != null; ) { 
      通过循环一直从queue中取出过期的entry,直至取完为止
            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) {
在同步代码块中先把queue中取出的Object类型的数据强制转化为Entry对象e,然后计算此entry在桶中的位置,然后开始遍历entry链表,如果此entry是链表头,设置此entry的后继为新的链表头
                        if (prev == e)
                            table[i] = next;
                        else
        然后将此entry的前序节点的后继指针指向此entry的后继节点
                            prev.next = next;
        设置被删除的entry的value为null,加速垃圾回收,相应的size--
                            e.value = null; // Help GC
                            size--;
                            break;
                    }
                    prev = p;
                    p = next;
                }
            

4、弱键的原理------>大致是通过WeakReference和ReferenceQueue来实现的。

实现步骤:(1)创建weakHashMap的时候,将键值对存放到数组链表当中;(2)当发生GC时会判断key是否有对象引用,如果没有引用了,就回收该key,意味着我们的entry实体从我们的集合中回收,回收的同时,将该对象加入到ReferenceQueue中;(3)在操作weakHashMap的时候,会首先同步table和Queue,table存放的是所有有效的键值对,Queue存放的是被回收的键值对,在table中删除Queue中有的键值对。

5、关于Java中的4种引用

(WeakHashMap中使用WeakReference,也就是通过虚引用来实现的)

(1)强引用(Strong Reference)--->永远不会回收被引用的对象,比如代码中new出来的对象

(2)软引用(SoftReference)--->表示有用但是非必需的,如果系统内存资源紧张,可能就会被回收

(3)弱引用(WeakReference)--->表示非必需的对象,只能存活到下一次垃圾回收发生之前

(4)虚引用(PhantomReference)--->是最弱的,该引用无法操作对象

6、哪些方法会产生清理元素的操作?

put、get方法开始的getTable会调用一次expungeStaleEntries

resize方法开始的getTable会调用一次expungeStaleEntries

transfer方法本身会判断弱引用指向的对象是否已经被GC

扩容之后发现size小于阈值的一半,会调用一次expungeStaleEntries

size方法会调用expungeStaleEntries

猜你喜欢

转载自blog.csdn.net/qq_40303781/article/details/84553030