说明:最近在学习Afinal框架,将一些心得分享给大家~
Afinal框架FinalBitmap缓存lru内存释放实现,核心是维护一个有最大值得LinkedHashMap:
1.FinalBitmap缓存通过类LruMemoryCache实现,以下是构造方法。初始化了最大缓存数量和初始化了一个LinkedHashMap对象。LinkedHashMap第一个参数表示实例化时容器大小,这里为0,会获得一个大小为1的容器,
第二个参数是一个因子,表示什么时候扩容(容器使用量为最大容量*因子时,容量扩大一倍),第三个参数是Lru算法的关键。true表示按照使用情况排序,false表示按照插入排序。
public LruMemoryCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
}
2.缓存插入put()算法,以下是源代码,可以看到put方法不允许有空的key或value,插入完成后,会执行entryRemoved的方法,该方法在LruMemoryCache中并没有任何操作。最后trimToSize()方法对容器进行了调整。
<pre style="font-family: Consolas; font-size: 12pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java">public final V put(K key, V value) {
if (key == null || value == null) {
throw new NullPointerException("key == null || value == null");
}
V previous;
synchronized (this) {
putCount++;
size += safeSizeOf(key, value);
previous = map.put(key, value);
if (previous != null) {
size -= safeSizeOf(key, previous);
}
}
if (previous != null) {
entryRemoved(false, key, previous, value);
}
trimToSize(maxSize);
return previous;
}
3.trimToSize实现通过循环自减实现:
while (true) {
..
synchronized (this) {
..
if (size <= maxSize || map.isEmpty()) {
break;
}
Map.Entry<K, V> toEvict = map.entrySet().iterator().next();
key = toEvict.getKey();
..
map.remove(key);
size -= safeSizeOf(key, value);//safeSizeOf(key, value)为1
..
}
}
到这里基本上lru的实现已经比较清晰了。