转载请注明源出处:http://www.cnblogs.com/lighten/p/7423818.html

1.前言

  本章介绍一下WeakHashMap,这个类也很重要。要想明白此类的作用,先要明白Java定义的四种引用类型。传送门。这里简单概括一下这四种引用:

  1.强引用:一般new出来的对象都属于强引用,只要该引用不是JVM回收机制回收的对象,就不会被清理。

  2.软引用:使用SoftReference包装的强引用对象是软引用。在JVM内存存够的情况下,软引用的对象不会被回收,JVM将抛出OOM异常的时候,会按没有被使用的时间顺序回收软引用对象。也就是说SoftReference这个对象持有强引用不会对JVM造成干扰,JVM会判断该对象有没有被SoftReference对象以外的对象持有来判断其属于强引用还是软引用,只有SoftReference持有该对象引用时,该对象才是一个软引用。所以使用SoftReference.get方法可能获得强引用对象,也可能是null。这里要注意的是,SoftReference对象本身也是一个强引用对象,如果其持有的强引用被回收了,这个对象也没有存在的意义了,所以这个是需要我们进行清理的。在其构造方法中提供了一个ReferenceQueue对象,在SoftReference持有对象被回收了后,会自动加入这个queue,之后通过queue中有没有这个对象,清理掉这个引用就可以了。

  3.弱引用:和软引用基本一致,不过其使用的是类WeakReference进行包装,而且JVM进行回收时就会回收掉该对象。其它的要点基本一致。

  4.虚引用:使用PhantomReference进行包装,其与软引用和弱引用的机制不一样。其不会获得所持有对象,直接返回的就是null,只有在对象被回收才会被加入队列中。

  根据这种中引用的特性,如何利用就仁者见仁智者见智了。

2.WeakHashMap

  这个Map的特点就是其键是虚引用,当垃圾回收器触发时,并不会阻止键被回收。意味着键值对会自动移除,当键不再被正常使用的时候。空的key和value都是被允许的,整个和HashMap比较像,非同步类。实际上JDK8的WeakHashMap并没有像HashMap那么复杂,实现还是十分简单的,就是一个hash表,处理冲突就是使用了链表。

  数据结构就是一个普通的table,还有就是hashmap中见到的threshold和loadfactor了。queue就是WeakHashMap虚引用的特有对象。

  get方法就是先处理key为Null的情况,再计算在table中的下标,这个链表遍历,找到引用相等或引用相等的键,返回其值。这里面要注意的就是getTable方法,其实际上就是对table进行了清理。

  当一个键没有被使用的时候,就会被GC回收,回收后就会进入queue中,getTable就是预先对表中废弃的键进行了清理。

  put方法也是先对表中废弃的键进行清理,然后找到其位置,存在就替换旧值,不存在就插入到链表首位。数量超过阈值就扩容hash表。

  remove方法就不再进行介绍了,操作原理都是一样的。所有涉及对表的操作,都会进行getTable()清理没有再被使用的键。WeakHashMap就可以简单的实现自动销毁不需要的键值了。

  其它的也没有什么描述的必要。

3.用例测试

    @Test
public void testWeakHashMap() {
WeakHashMap<Object, String> whm = new WeakHashMap<>();
Object one = new Object();
Object two = new Object();
whm.put(one, "one");
whm.put(two, "two");
one = null;
System.out.println(whm.size());
System.gc();
System.out.println(whm.size());
System.out.println(whm.get(two));
}

  上面这个测试代码在我这里允许多次出现了两个结果:

  2,1,two

  2,2,two

  所以gc发生的时间和弱引用进入队列的时间以及WeakHashMap清理废弃键的时间都是不确定的。这个类的使用也就是将一些资源value与键的生命周期绑定。键结束了value也就会被清除。前提是要触发WeakHashMap的相关方法。

Java之集合(十三)WeakHashMap的更多相关文章

  1. Java中的集合(十三) 实现Map接口的Hashtable

    Java中的集合(十三) 实现Map接口的Hashtable 一.Hashtable简介 和HashMap一样,Hashtable采用“拉链法”实现一个哈希表,它存储的内容是键值对(key-value ...

  2. 谈谈Java的集合组件

    让我们一起谈谈Java的集合组件 我们在使用Java的时候,都会遇到并使用到Java的集合.在这里通过自己的理解和网上的资源对Java的集合方面的使用做一个简单的讲解和总结. Java主要分为3个集合 ...

  3. Java:集合,Map接口框架图

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  4. 对JAVA的集合的理解

    对JAVA的集合的理解是相对于数组 1.数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型) 2.JAVA集合可以存储和操作数目不固定的一组数据.  3.所有的JAVA集合都位 ...

  5. <<Effective Java>> 第四十三条

    <<Effective Java>> 第四十三条:返回零长度的数组或者集合,而不是null 如果一个方法的返回值类型是集合或者数组 ,如果在方法内部需要返回的集合或者数组是零长 ...

  6. 【Java】集合_学习笔记

    一.集合 1.集合类也称容器类,主要负责保存.盛装其他数据. 2.集合可以保存数量不确定的数据,保存具有映射关系的数据(也称关联数组). 3.Java5后提供一些多线程安全的集合类,放在java.ut ...

  7. JAVA EE的十三种技术

    java ee 的十三中技术 一.jdbc 1). jdbc-odbc桥 2). jdbc-native 驱动桥 3). jdbc-network 桥 4). 纯java驱动 二. java命令和目录 ...

  8. Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章

    原创文章,转载请务注明出处 OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使 ...

  9. java的集合框架最全详解

    java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...

随机推荐

  1. systemctl自定义service

    应用场景:开启自启动运行脚本/usr/local/manage.sh 一.服务介绍 CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户 ...

  2. RAC环境数据库重启实例

    1.重启之前最好先看一下节点信息和运行状态 可以通过srvctl status database -d 数据库名 //查看节点信息 Crs_stat //查看节点状态 可以看到数据节点它由两个实例组成 ...

  3. C++之类和对象的使用(二)

    析构函数 析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一系列清理工作,使这部分内存可以被程序分配给新对象使用.对象生命周期结束,程序就自动执行析构函数来完成这些工作. 析构函数是一种 ...

  4. 编译hbase-1.2.3源代码

    目录 目录 1 1. 约定 1 2. 安装jdk 1 3. 安装maven 1 4. 网络配置 2 4.1. eclipse 3 4.2. maven 3 5. 从hbase官网下载源代码包: 4 6 ...

  5. AE和Mocha结合做视频后期制作

    AE:After Effects Mocha:视频图像追踪软件 智能抠像 前提:安装QuickTime视频编码器!4.1版,不然视频无法预览播放 >>关于AE CC自带的mocha 插件和 ...

  6. OpenGL ES 光照模型之——环境光照(RenderMonkey测试)

    概述及目录(版权所有,请勿转载 www.cnblogs.com/feng-sc/) 本文总结如何在RenderMonkey下做简单的OpenGL ES环境光光照模型测试. 主要包括如下内容: 1.使用 ...

  7. vim 配置半透明

    转载两个博客 链接一 链接二

  8. mySQl数据库中不能插入中文的处理办法

    1. 修改MySQL安装目录下(C:\Program Files\MySQL\MySQL Server 5.5)的my.ini文件 设置: default-character-set=utf8 cha ...

  9. js常用的原生方法

    JavaScript pow() 方法 pow() 方法可返回 x 的 y 次幂的值 语法 Math.pow(x,y) 参数 描述 x 必需.底数.必须是数字. y 必需.幂数.必须是数字. 返回值 ...

  10. 关于C_Sharp集中处理异常

    1.写在前面 “异常意味着什么?”,想必不用对此做多余的解释,我们有理由相信在任何情况下任何应用程序都有可能出现异常,若在程序中没有对异常进行处理,则操作系统会以粗暴的方式处理掉它(弹出错误提示框), ...