首先 我们从他的构造方法及属性看起
private final LinkedHashMap<K, V> map;
/** Size of this cache in units. Not necessarily the number of elements. */
private int size;
private int maxSize;
private int putCount;
private int createCount;
private int evictionCount;
private int hitCount;
private int missCount;
/**
* @param maxSize for caches that do not override {@link #sizeOf}, this is
* the maximum number of entries in the cache. For all other caches,
* this is the maximum sum of the sizes of the entries in this cache.
*/
public LruCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
}
从构造方法可以看出 需要传入一个Int值 和new了一个LinkedHashMap对象 然后我们接着往后面的方法看
/**
* Sets the size of the cache.
* @param maxSize The new maximum size.
*
* @hide
*/
public void resize(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
synchronized (this) {
this.maxSize = maxSize;
}
trimToSize(maxSize);
}
首先我们从上面的注解可以知道这个是设置缓存大小的方法 我们可以看出 它吧从构造函数传过来的 maxsize这个值放入了 trimToSize(maxSize); 这个方法中 接着我们进入这个方法里面去看看
/**maxSize 表示在返回内存大小之前的最大数值
* @param maxSize the maximum size of the cache before returning. May be -1
* to evict even 0-sized elements.
*/
private void trimToSize(int maxSize) {
while (true) {
K key;
V value;
synchronized (this) {
//判断集合是否为空 size是否小于0
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(getClass().getName()
+ ".sizeOf() is reporting inconsistent results!");
}
如果小于设定的最大值 则跳出循环
if (size <= maxSize) {
break;
}
// BEGIN LAYOUTLIB CHANGE
// get the last item in the linked list.
// This is not efficient, the goal here is to minimize the changes
// compared to the platform version.
//遍历 LinkedHashMap 双向链表的元素,取得队列尾部的元素(就是我们所说的过期元素),如果它不为空,就将它移除。
Map.Entry<K, V> toEvict = null;
for (Map.Entry<K, V> entry : map.entrySet()) {
//不断的把entry 的值赋给toEvict 直到最后一个
toEvict = entry;
}
// END LAYOUTLIB CHANGE
if (toEvict == null) {
break;
}
key = toEvict.getKey();
value = toEvict.getValue();
//移除最后一个元素
map.remove(key);
/*
private int safeSizeOf(K key, V value) {
int result = sizeOf(key, value);
if (result < 0) {
throw new IllegalStateException("Negative size: " + key + "=" + value);
}
return result;
}
*/
//判断移除后的缓存大小
size -= safeSizeOf(key, value);
evictionCount++;
}
entryRemoved(true, key, value, null);
}
}
最主要的方法分析完了 再看看其他的
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;
}
网友评论