文档章节

使用ReferenceQueue和ReferenceQueue实现的SoftReferenceMap

SuShine
 SuShine
发布于 2014/04/06 15:29
字数 507
阅读 881
收藏 1

这几天没事看看代码, 发现了一个SoftReferenceMap的东西, 这个东西是自定义的 实际上是利用SoftReference和ReferenceQueue来搭配从而达到避免oom的功能

发现这个东西实现的还是挺好玩的, 在之前新浪的面试中也遇到过这样的问题, 现在想来感觉回答的不是很好. 现在看到这个代码, 感觉那个面试官要的估计就是这个东西: 架构如图:

代码+注释:

/**
 * 继承map是为了在UIManager中 自由切换 map 和softregerencemap
 */
public class SoftReferenceMap<K, V> extends HashMap<K, V> {
	private static final long serialVersionUID = 1L;
	// 将 V 对象封装成软引用的对象,放置在SoftReferenceMap里面
	private HashMap<K, SoftValue<K, V>> temp;
	//用来存储键入了系统回收队列中的对象, 这里对应的是V
	private ReferenceQueue<V> queue;

	public SoftReferenceMap() {
		super();
		this.temp = new HashMap<K, SoftValue<K, V>>();
		queue = new ReferenceQueue<V>();
	}

	@Override
	public boolean containsKey(Object key) {
		// 清空正在被系统回收队列, 否则可能拿到的SoftReference中可能已经没有了 key对应的对象了
		clearMap();
		return temp.containsKey(key);
	}

	@Override
	public V get(Object key) {
		clearMap();
		SoftValue<K, V> softValue = temp.get(key);
		if (softValue != null) {
			return softValue.get();
		}

		return null;
	}

	@Override
	public V put(K key, V value) {
		SoftValue<K, V> softReference = new SoftValue<K, V>(key, value, queue);
		temp.put(key, softReference);
		return null;
	}

	// 从temp中清空 已经键入了回收队列的 对象(V) 对应的SoftReference
	@SuppressWarnings("unchecked")
	private void clearMap() {
		//从quene中拿到当前已经加入回收队列的最后一个V 
		SoftValue<K, V> softReference = (SoftValue<K, V>) queue.poll();
		while (softReference != null) {
			temp.remove(softReference.key);//拿到这个V对应的key 把他从temp的map中删除
			softReference = (SoftValue<K, V>) queue.poll(); //循环把所有的在回收队列中的值从temp中删除
		}
	}

	//实现一个带键值对的SoftReference, 用来保存一个key供 temp 快速删除 对应的SoftReference
	@SuppressWarnings("hiding")
	private class SoftValue<K, V> extends SoftReference<V> {
		private K key;

		public SoftValue(K k, V v, ReferenceQueue<? super V> q) {
			super(v, q);//把SofrReference注册到Queue中, 系统会在适当时机把 V 加入到回收队列中.
			this.key = k;
		}
	}

}




© 著作权归作者所有

SuShine
粉丝 126
博文 574
码字总数 157991
作品 0
朝阳
后端工程师
私信 提问
对ReferenceQueue的疑问与研究

《java编程思想》17章讲到持有引用。其中有一个类ReferenceQueue。我不理解它是做什么用的。不理解处有以下几点: 1,当把ReferenceQueue对象传入Reference类的构造器后,即说明了Reference...

蚂蚁的世界
2015/07/05
0
0
理解 Java 的 GC 与 幽灵引用

Java 中一共有 4 种类型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference (传说中的幽灵引用 呵呵), 这 4 种类型的引用与 GC 有着密切的关系, 让我们逐一来...

长平狐
2012/10/09
98
0
Spark - 利用WeakReference来清理对象

注:本文转自我的个人博客(Spark - 利用WeakReference来清理对象)。 最近在stackoverflow上看到有人好奇Spark是在什么时机对Accumulator或者Broadcast这样的变量进行回收的。自己在看源码的...

廖嘉逸
03/11
0
0
Java堆外内存回收原理

简书 涤生。 转载请注明原创出处,谢谢! 如果读完觉得有收获的话,欢迎点赞加关注。 Java堆外内存回收原理 DirectByteBuffer简介 DirectByteBuffer这个类是JDK提供使用堆外内存的一种途径,...

涤生_YinQi
2017/04/13
0
0
WeakHashMap垃圾回收原理

WeakHashMap垃圾回收原理 简书 涤生。 转载请注明原创出处,谢谢! 如果读完觉得有收获的话,欢迎点赞加关注。 介绍 WeakHashMap自然联想到的是HashMap。确实,WeakHashMap与HashMap一样是个...

涤生_YinQi
2017/11/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

高并发场景下的缓存有哪些常见的问题?

一、缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。 这就比较依赖缓存的过期和更新...

别打我会飞
30分钟前
2
0
List list = new ArrayList()为何父类引用指向子类对象(多态)

态:要有继承,方法的重写,父类引用指向子类对象 疑问一:父类引用指向子类对象 与指向父类对象 Animal cat = new Cat(); //向上转型。 父类引用指向子类对象,该引用不能再访问子类新增加的...

architect刘源源
31分钟前
2
0
分而治之-快速排序

快速排序的思想: 快速排序首先在数组中确定1个枢纽项(比如数组中的第一个元素),将大于该枢纽项的元素放到右侧,小于该枢纽项的元素放到左侧,这样枢纽项将数组划分成两部分。接着继续对划...

万山红遍
今天
5
0
Qt编写自定义控件9-导航按钮控件

前言 导航按钮控件,主要用于各种漂亮精美的导航条,我们经常在web中看到导航条都非常精美,都是html+css+js实现的,还自带动画过度效果,Qt提供的qss其实也是无敌的,支持基本上所有的CSS2属...

飞扬青云
今天
4
0
Python开发工具:pyJasper

原文:https://www.oschina.net/p/pyjasper 前言 pyJasper是 JasperReports 网络服务器的 Python 客户端。 pyJasper 是一组 Python 基础工具,可以用来处理 JasperReports 报表 。因为 Jasper...

A_裙232550246
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部