转载请注明源出处: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. MySQL之SQL语句零碎总结

    一.MySQL中有个ifnull函数,跟Oracle的nvl类似,用法如下: select* from Ta t where ifnull(pro, 0) < 100; 解释:当pro是null ...

  2. 配置 cxf-ws spring bean 文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  3. android 热更新nuwa

    简介 Nuwa是比较流行的一种Android热补丁方案的开源实现,它的特点是成功率高,实现简单.当然,热补丁的方案目前已经有很多了,AndFix, Dexposed, Tinker等,之所以要分析Nu ...

  4. 基于MATLAB的均值滤波算法实现

    在图像采集和生成中会不可避免的引入噪声,图像噪声是指存在于图像数据中的不必要的或多余的干扰信息,这对我们对图像信息的提取造成干扰,所以要进行去噪声处理,常见的去除噪声的方法有均值滤波.中值滤波.高斯滤 ...

  5. MyEclipse2014中Java类右键Run as没有JUnit Test

    Java初学,想试试连接本地数据库,按照百度经验中的方法,在最后执行测试的卡住了,为啥?因为MyEclipse中右键Run as没有JUnit Test选项! 6.1.测试数据库mysql是在项目中连 ...

  6. Spring MVC深入讲解

    一.前言: 大家好,Spring3 MVC是非常优秀的MVC框架,由其是在3.0版本发布后,现在有越来越多的团队选择了Spring3 MVC了.Spring3 MVC结构简单,应了那句话简单就是美,而 ...

  7. 如何关闭D10 启动后自动打开的 WelCome页

    在快捷方式上 修改为 "C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\bds.exe" -pDelphi -np 最后增加 ...

  8. winform NPOI excel 导出并选择保存文件路径

    public void ExcelOp(DataGridView gdv,ArrayList selHead) { if (selHead.Count==0) { MessageBox.Show(&q ...

  9. C#使用PriorityQueue

    #pragma once #include<cliext/queue> #include<cliext/vector> using namespace cliext; usin ...

  10. Docker registry 私有仓库镜像查询、删除、上传、下载 shell

    #Docker官方私有仓库registry #官方只提供了API接口,不方便使用,就写了个shell #docker-registry安装配置http://www.cnblogs.com/elvi/p ...