WeakHashMap和HashMap的区别

WeakHashMap和HashMap的区别

前面对HashMap的源码和WeakHashMap的源码分别进行了分析。在WeakHashMap源码分析博文中有对与HashMap区别的比较,但是不够具体系统。加上本人看了一些相关的博文,发现了一些好的例子来说明这两者的区别,因此,就有了这篇博文。

WeakHashMap和HashMap一样,WeakHashMap也是一个散列表,它存储的内容也是键值对(key-value)映射,而且键和值都可以为null。不过WeakHashMap的键是“弱键”(注:源码中Entry中的定义是这样的:private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>,即Entry实现了WeakReference类),当WeakHashMap某个键不再正常使用时,会被从WeakHashMap自动删除。更精确的说,对于一个给定的键,其映射的存在并不能阻止垃圾回收器对该键的丢弃,这就使该键称为被终止的,被终止,然后被回收,这样,这就可以认为该键值对应该被WeakHashMap删除。因此,WeakHashMap使用了弱引用作为内部数据的存储方案,,WeakHashMap可以作为简单缓存表的解决方案,当系统内存不足时,垃圾收集器会自动的清除没有在任何其他地方被引用的键值对。如果需要用一张很大的Map作为缓存表时,那么可以考虑使用WeakHashMap。

从源码的角度,我们来分析下上面这段话是如何来工作的??

在WeakHashMap实现中,借用了ReferenceQueue这个“监听器”来保存被GC回收的”弱键”,然后在每次使用WeakHashMap时,就在WeakHashMap中删除ReferenceQueue中保存的键值对。即WeakHashMap的实现是通过借用
ReferenceQueue这个“监听器”来优雅的实现自动删除那些引用不可达的key的。关于ReferenceQueue会在下篇博文中进行介绍

具体如下:

WeakHashMap是通过数组table保存Entry(键值对);每个Entry实际上就是一个链表来实现的。当某“弱键”不再被其它对象引用,就会被GC回收时,这个“弱键”也同时被添加到ReferenceQueue队列中。当下一步我们需要操作WeakHashMap时,会先同步table、queue,table中保存了全部的键值对,而queue中保存的是GC回收的键值对;同步他们,就是删除table中被GC回收的键值对。

源码中完成“删除”操作的函数代码如下:

    /**
     * Expunges stale entries from the table.
     *翻译:删除过时的条目,即将ReferenceQueue队列中的对象引用全部在table中给删除掉
     *思路:如何删除一个table的节点e,方法为:首先计算e的hash值,接着根据hash值找到其在table的位置,然后遍历链表即可。
     */
    private void expungeStaleEntries() {
        for (Object x; (x = queue.poll()) != null; ) {
            synchronized (queue) {
                @SuppressWarnings("unchecked")
                    Entry<K,V> e = (Entry<K,V>) x;
                
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值