在开始阅读这篇博文前,需要一点点java基础的储备知识
1.ReferenceQueue的作用,我上一篇博文有比较深入的讲解。
2.简单了解LRU算法,我在这里推荐两篇快速了解并学习LRU算法的博文链接:
http://blog.csdn.net/Ackarlix/archive/2007/08/26/1759793.aspx
http://liangwj72.iteye.com/blog/123856
直接上代码
package cn.itcast.camera.gallery;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* LruCache(对象缓冲池)用于缓存对象,有些图片或者视频在界面上显示,如果每次都从数据库去取(图片或视频文件以二进制流的形式存在数据库中),
* 就会加应用处理的负担
* ,用LruCache就能解决此问题,只要第一次从数据库中取出,然后把取出的东西放在LRUCache中,之后每次就可以从LRUCache中去取了
* ,加快访问速度。并有效地节省内存。
*/
public class LruCache<K, V> {
//mLruMap:一个简单实现LRU算法的LinkedHashMap
private final HashMap<K, V> mLruMap;
//mWeakMap:保存 弱引用对象Entry
private final HashMap<K, Entry<K, V>> mWeakMap = new HashMap<K, Entry<K, V>>();
//mQueue:记录引用对象已被垃圾回收器回收过的Entry
private ReferenceQueue<V> mQueue = new ReferenceQueue<V>();
//设定LruCache固定存储的最大容量
@SuppressWarnings("serial")
public LruCache(final int capacity) {
mLruMap = new LinkedHashMap<K, V>(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
//LRU算法最关键的一步,自动清除过期数据,始终保证mLruMap 的size<=capacity,即mLruMap 内存占用总大小<=单个对象所占内存*capacity
return size() > capacity;
}
};
}
private static class Entry<K, V> extends WeakReference<V> {
//保存Key值,以便mWeakMap删除已被垃圾回收器回收过的弱引用对象Entry
K mKey;
public Entry(K key, V value, ReferenceQueue<V> queue) {
super(value, queue);
mKey = key;
}
}
//清空mWeakMap里已被垃圾回收器回收过的Entry(表明Entry所引用的对象已经被垃圾回收器回收,这时需要清除Entry对象本身)
@SuppressWarnings("unchecked")
private void cleanUpWeakMap() {
Entry<K, V> entry = (Entry<K, V>) mQueue.poll();
//一旦垃圾回收器回收该Entry所引用的对象,就从mWeakMap里删除该Entry
while (entry != null) {
mWeakMap.remove(entry.mKey);
entry = (Entry<K, V>) mQueue.poll();
}
}
//将对象放入缓存,并保存弱引用
public synchronized V put(K key, V value) {
cleanUpWeakMap();
mLruMap.put(key, value);
Entry<K, V> entry = mWeakMap.put(key, new Entry<K, V>(key, value, mQueue));
return entry == null ? null : entry.get();
}
//取得对象
public synchronized V get(K key) {
cleanUpWeakMap();
V value = mLruMap.get(key);
if (value != null)
return value;
Entry<K, V> entry = mWeakMap.get(key);
return entry == null ? null : entry.get();
}
//清空
public synchronized void clear() {
mLruMap.clear();
mWeakMap.clear();
mQueue = new ReferenceQueue<V>();
}
}