一、类继承关系
二、概述
WeakHashMap是基于基于弱引用key和哈希表的Map接口实现类,通常用于实现对内存敏感的本地缓存。使用WeakHashMap时要求key不能被其他常驻内存的实例(如WeakHashMap中的value)引用,如果必须引用,则将引用方包装成WeakReference,如:m.put(key, new WeakReference(value))。当只有WeakHashMap实例保留了对目标key的引用时,下一次垃圾回收可能将该key从内存中删除掉,注意key删除了但是key对应的WeakReference实例还在WeakHashMap中。如果被删除了,则下一次调用WeakHashMap的某个方法时,WeakHashMap会首先将被垃圾回收掉的key对应的WeakReference实例及其value从WeakHashMap中删除。使用WeakHashMap时需要程序做好某个key突然没有的应对措施,key的删除是垃圾回收器决定的,对应用程序是不可控不可预知的。参考如下用例:
@Test
public void test() throws Exception {
ReferenceQueue queue = new ReferenceQueue();
WeakReference reference = new WeakReference(new Object(), queue);
System.out.println(reference);
System.gc();
Reference reference1 = queue.remove();
System.out.println(reference1);
System.out.println(reference1.get());//为null
}
@Test
public void test2() throws Exception {
Map<User,String> map=new WeakHashMap<>();
map.put(new User("shl",12),"shl");
map.put(new User("shl2",12),"shl2");
System.out.println(map.size());
//调用gc()方法时不保证垃圾回收器一直执行垃圾回收
System.gc();
System.gc();
System.gc();
System.out.println(map.size());
}
三、源码实现
1、全局变量定义
/**
* 默认初始容量
*/
private static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
* 最大容量
*/
private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* 默认负载因子
*/
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* 哈希表
*/
Entry<K,V>[] table;
/**
* 保存的元素个数
*/
private int size;
/**
* 执行扩容的阈值 (capacity * load factor).
*/
private int threshold;
/**
* 负载因子
*/
private final float loadFactor;
/**
* 保存弱引用的队列,当垃圾回收器回收了某个弱引用对应的对象时,会将该弱引用放入队列中
*/
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
/**
* 代表为null的key
*/
private static final Object NULL_KEY = new Object();
/**
* 记录修改次数
*/
int modCount;
2、构造方法
public WeakHashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Initial Capacity: "+
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal Load factor: "+
loadFactor);
int capacity = 1;
//计算大于initialCapacity的最小的2的整数次方,跟HashMap中的实现相比,运算的次数更多
while (capacity < initialCapacity)
capacity <<= 1;
table = newTable(capacity);
this.loadFactor = loadFactor;
thresh