看看人家 - Glide的LruCache
在android领域,glide是一个非常优秀的图片加载框架,优秀自然有优秀的道理,看github的star你会发现它非常受欢迎,今天有空来看看Glide中LruCache的实现,源码阅读我还是坚持这个原则:不着急关注细节,先抽取骨架,再薅皮毛
1,基本操作接口
我们在使用LRU之类的实现框架的时候,这四个方法基本概况了所有日常,加锁的原因是为了保证线程安全和数据一致。
/**
* T = key
* Y = value
*/
public class LruCache<T, Y> {
/**
* 缓存中是否包含此KEY
*/
public synchronized boolean contains(T key);
/**
* 从缓存中获取目标数据
*/
public synchronized Y get(T key);
/**
* 把item放入缓存
*/
public synchronized Y put(T key, Y item);
/**
* 从缓存中移除
*/
public synchronized Y remove(T key);
}
2,逃不掉的基本数据结构
我们都知道LRU大部分都使用链表这个基本数据结构来实现,但是链表的访问效率又不理想,使用LinkedHasmap是个不错的选择,我们来看下LruCache的定义。
public class LruCache<T, Y> {
/**初始容量100,加载因子0.75,也就是说当容量达到75%,就触发扩容机制。同时按照访问顺序排序*/
private final Map<T, Entry<Y>> cache = new LinkedHashMap<>(100, 0.75f, true);
private final long initialMaxSize;
private long maxSize;
private long currentSize;
...
使用LinkedHasmap兼顾了插入,删除,访问的效率。那么我们接下来观察一下细节,先看一下put的实现。
3,实现细节
3.1 put
put分两种情况,一种是key不存在,是添加;另一种是key已经存在,就替换。
public synchronized Y put(@NonNull T key, @Nullable Y item) {
//itemSize始终为1
final int itemSize = getSize(item);
//边界处理,我们的LruCache容量初始化的时候不能为1
if (itemSize >= maxSize) {
//这个onItemEvicte