Java学习-容器-WeakHashMap

版权声明:欢迎转载,请注明作者和出处 https://blog.csdn.net/baichoufei90/article/details/83551202

Java学习-容器-WeakHashMap

0x01 摘要

本文简要介绍弱引用的典型应用-WeakHashMap。

0x02 基础概念

WeakHashMap是一个特殊的map,有着弱引用的key。也就是说,当某个key没有再被正常使用时,WeakHashMap中的这个key对应的entry会被自动移除。更准确的说,一个拥有一个指定的key的mapping映射存在也不能阻止该key被GC回收。当一个key被GC回收掉后,他的entry会从该Map中被高效移除掉。这一点是WeakHashMap与其他map最大的不同之处。

当使用 WeakHashMap 时,即使没有显示的添加或删除任何元素,即使你使用了synchronize获取改weakHashMap实例对象锁,也可能发生如下情况:

  • 调用两次size()方法返回不同的值;
  • 两次调用isEmpty()方法,第一次返回false,第二次返回true;
  • 两次调用containsKey()方法,第一次返回true,第二次返回false,尽管两次使用的是同一个key;
  • 两次调用get()方法,第一次返回一个value,第二次返回null,尽管两次使用的是同一个对象。

0x03 容器特点

WeakHashMap特点如下:

  • key为弱引用,所以可能随时从map中移除对应的entry
  • 新增元素时 key 和 value 都能为 null
  • 非线程安全,必须用Collections.synchronizedMap(new WeakHashMap<>())
  • 主要适用于那些key使用==来判断是否相等的对象。一旦该key被GC回收那么不可能再重造一个完全相同对象,也就不能再用相同对象key到WeakHashMap中查找导致到结果
  • value为强引用。注意一定不能让value直接或间接引用他自己的key,否则会让key永不删除
  • 由此类的所有“集合视图方法”返回的集合的iterator()方法返回的迭代器有快速失败fail-fast 特性:即当iterator创建后,该map发生了结构性变化,那么调用除了迭代器自身的remove方法外的任何方法都会导致抛出ConcurrentModificationException。但要注意,这个特性并不是百分百可靠的。

0x04 使用示例

import java.util.Iterator;
import java.util.WeakHashMap;

/**
 * Created by chengc on 2018/10/30.
 */
public class WeakHashMapTest2 {
    public static void main(String[] args) {
        WeakHashMap weakHashMap = new WeakHashMap<String, Object>();
        final int SIZE = 10;
        String[] str = new String[SIZE];
        for (int i = 0; i < SIZE; i++){
            String key = String.valueOf(i);
            String value = String.valueOf(i);
            // 保留偶数到String[],也就是偶数位有强引用
            if(i % 2 == 0){
                str[i] = key;
            }
            // 全部数字放入weakHashMap
            weakHashMap.put(key, value);
        }
        // 显示调用gc
        System.gc();

        // 遍历weakHashMap
        Iterator iter = weakHashMap.keySet().iterator();
        while(iter.hasNext()){
            System.out.println(weakHashMap.get(iter.next()));
        }
    }
}

以上例子中,因为将偶数放入String数组中,所以就有相应的强引用,其他奇数都是弱引用。
在gc过后,遍历结果就只剩偶数了,奇数都因为只有弱引用key而被GC干掉了。

猜你喜欢

转载自blog.csdn.net/baichoufei90/article/details/83551202