转载请注明源出处: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. spring boot使用java读取配置文件,DateSource测试,BomCP测试,AnnotationConfigApplicationContext的DataSource注入

    一.配置注解读取配置文件         (1)@PropertySource可以指定读取的配置文件,通过@Value注解获取值   实例:           @PropertySource(val ...

  2. QDesktopWidget

    在Qt中提供了QDesktopWidget类,提供屏幕的有关信息. 可以这么作: QDesktopWidget *d=QApplication::desktop(); int width=d-> ...

  3. day8 异常处理

    异常和错误 part1:程序中难免出现错误,而错误分成两种 1.语法错误(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) 2.逻辑错误(逻辑错误) part2:什么是异常 ...

  4. hdu 1014

    我:题都看不懂 路人甲:这是随机数分配题目 路人乙:这是求生成元,求mod N的生成元,即生成元与N互质 路人丙:这是根据给出的递推公式算一下 0~ mod-1之间的数是否都有出现过,如果都出现了,那 ...

  5. Python学习-32.Python中os模块的一些方法

    首先肯定是要引入os模块了. import os getcwd方法: print(os.getcwd()) 上面的语句将会输出当前的工作目录,相当于C#中的Environment.CurrentDir ...

  6. 两种方式创建支持SSH服务的docker镜像

    方法一:基于commit命令创建 1.首先,从docker的源中查看我们需要的镜像,本案例中使用Ubuntu作为基础镜像. # federico @ linux in ~ [16:57:38] $ s ...

  7. LINQ to XML基本操作

    Linq to XML同样是对原C#访问XML文件的方法的封装,简化了用xpath进行xml的查询以及增加,修改,删除xml元素的操作. LINQ to XML 三个最重要类:XElement.XAt ...

  8. [JS] Ajax请求会话过期处理

    对于页面来说,处理session过期比较简单,一般只需在过滤器里面判断session用户是否存在,不存在则跳转页面到登陆页即可. 对于Ajax请求来说,这个办法则无效,只能获取到登录页的html代码. ...

  9. wpf控件拖动

    Thumb 拖动 上代码! <Window x:Class="Thumb控件移动.MainWindow" xmlns="http://schemas.microso ...

  10. 《ASP.NET MVC 5 破境之道》:第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造

    第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造 MVC默认模板的视觉设计从MVC1到MVC3都没有改变,比较陈旧了:在MVC4中做了升级,好看些,在不同的分辨率下,也能工作得 ...