栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

浅谈(Java)WeakHashMap源码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

浅谈(Java)WeakHashMap源码

博主介绍:程序员悟啦(乌拉~)

✍个人仓库:码云

座右铭:“懒”对一个人的毁灭性有多大,早起的重要性就多大。

免责声明:文章由博主原创、部分文章整理于网络,仅供学习和知识分享

相遇是缘,既然来了就拎着小板凳晴坐下来一起唠会儿‍,如果在文中有所收获,请别忘了一键三连,动动你发财的小手,你的鼓励,是我创作的动力襤!


文章目录
  • Map - WeakHashMap源码解析
    • JDK版本
    • 总体介绍
    • 具体实现
    • Weak HashSet

Map - WeakHashMap源码解析 JDK版本

JDK 1.8.0_110

总体介绍

介绍一个特殊的成员: WeakHashMap,从名字可以看出它是某种 Map。它的特殊之处在于 WeakHashMap 里的entry可能会被GC自动删除,即使程序员没有调用remove()或者clear()方法。

更直观的说,当使用 WeakHashMap 时,即使没有显示的添加或删除任何元素,也可能发生如下情况:

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

遇到这么奇葩的现象,是不是觉得使用者一定会疯掉?

**其实不然,WeakHashMap的这个特点特别适用于需要缓存的场景。**在缓存场景下,由于内存是有限的,不能缓存所有对象;对象缓存命中可以提高系统效率,但缓存MISS也不会造成错误,因为可以通过计算重新得到。

要明白 WeakHashMap 的工作原理,还需要引入一个概念 : 弱引用(WeakReference)。我们都知道Java中内存是通过GC自动管理的,GC会在程序运行过程中自动判断哪些对象是可以被回收的,并在合适的时机进行内存释放。GC判断某个对象是否可被回收的依据是,是否有有效的引用指向该对象。如果没有有效引用指向该对象(基本意味着不存在访问该对象的方式),那么该对象就是可回收的。这里的有效引用 并不包括弱引用。也就是说,虽然弱引用可以用来访问对象,但进行垃圾回收时弱引用并不会被考虑在内,仅有弱引用指向的对象仍然会被GC回收。

WeakHashMap 内部是通过弱引用来管理entry的,弱引用的特性对应到 WeakHashMap 上意味着什么呢?将一对key, value放入到WeakHashMap里并不能避免该key值被GC回收,除非在 WeakHashMap之外还有对该key的强引用。

Java中引用也是分种类的,并且不同种类的引用对GC的影响不同就够了。

具体实现

WeakHashMap的存储结构类似于Map - HashSet & HashMap 源码解析

Weak HashSet

Java Collections工具类给出了解决方案,Collections.newSetFromMap(Map map)方法可以将任何 Map包装成一个Set。通过如下方式可以快速得到一个 Weak HashSet:

// 将WeakHashMap包装成一个Set
Set weakHashSet = Collections.newSetFromMap(
        new WeakHashMap());
 

不出所料,newSetFromMap()方法只是对传入的 Map做了简单包装:

// Collections.newSetFromMap()用于将任何Map包装成一个Set
public static  Set newSetFromMap(Map map) {
    return new SetFromMap<>(map);
}

private static class SetFromMap extends AbstractSet
    implements Set, Serializable
{
    private final Map m;  // The backing map
    private transient Set s;       // Its keySet
    SetFromMap(Map map) {
        if (!map.isEmpty())
            throw new IllegalArgumentException("Map is non-empty");
        m = map;
        s = map.keySet();
    }
    public void clear()               {        m.clear(); }
    public int size()                 { return m.size(); }
    public boolean isEmpty()          { return m.isEmpty(); }
    public boolean contains(Object o) { return m.containsKey(o); }
    public boolean remove(Object o)   { return m.remove(o) != null; }
    public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
    public Iterator iterator()     { return s.iterator(); }
    public Object[] toArray()         { return s.toArray(); }
    public  T[] toArray(T[] a)     { return s.toArray(a); }
    public String toString()          { return s.toString(); }
    public int hashCode()             { return s.hashCode(); }
    public boolean equals(Object o)   { return o == this || s.equals(o); }
    public boolean containsAll(Collection c) {return s.containsAll(c);}
    public boolean removeAll(Collection c)   {return s.removeAll(c);}
    public boolean retainAll(Collection c)   {return s.retainAll(c);}
    // addAll is the only inherited implementation
    ......
}

如在文中有所收获,请点赞+关注,传统美德不能丢


转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号