LruCache

作者: HOLLE_karry | 来源:发表于2020-05-09 15:36 被阅读0次

    1.三级缓存

    ⑴为什么要使用三级缓存

    如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了,假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量。在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响,特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知,所以提出三级缓存策略,通过网络、本地、内存三级缓存图片,来减少不必要的网络交互,避免浪费流量

    ⑵什么是三级缓存

    内存中的缓存>本地缓存>网络缓存
    •网络缓存, 不优先加载, 速度慢,浪费流量
    •本地缓存, 次优先加载, 速度快
    •内存缓存, 优先加载, 速度最快

    2.LRU概述及原理

    LruCache中Lru算法的实现就是通过LinkedHashMap来实现的。LinkedHashMap继承于HashMap,它使用了一个双向链表来存储Map中的Entry顺序关系,这种顺序有两种,一种是LRU顺序,一种是插入顺序,这可以由其构造函数public LinkedHashMap(int initialCapacity,float loadFactor, boolean accessOrder)指定。所以,对于get、put、remove等操作,LinkedHashMap除了要做HashMap做的事情,还做些调整Entry顺序链表的工作。LruCache中将LinkedHashMap的顺序设置为LRU顺序来实现LRU缓存,每次调用get(也就是从内存缓存中取图片),则将该对象移到链表的尾端。调用put插入新的对象也是存储在链表尾端,这样当内存缓存达到设定的最大值时,将链表头部的对象(近期最少用到的)移除。

    声明的变量

        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;
    

    •map:存放数据的集合
    •size:当前LruCahce的内存占用大小
    •maxSize:Lrucache的最大容量
    •putCount:put的次数
    •createCount:create的次数
    •evictionCount:回收的次数
    •hitCount:命中的次数
    •missCount:丢失的次数
    构造函数

    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);
    }
    

    3.LRU算法案例

    //当设置为true的时候:
    public static final void main(String[] args) {
            LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>(0, 0.75f, true);
            map.put(0, 0);
            map.put(1, 1);
            map.put(2, 2);
            map.put(3, 3);
            map.put(4, 4);
            map.put(5, 5);
            map.put(6, 6);
            map.get(1);
            map.get(2);
            for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                System.out.println(entry.getKey() + ":" + entry.getValue());
            }
        }
    

    输出结果为:

    0:0
    3:3
    4:4
    5:5
    6:6
    1:1
    2:2
    

    当设置为false的时候,输出顺序为:

    0:0
    1:1
    2:2
    3:3
    4:4
    5:5
    6:6
    

    总结:

    有以上结果可以看出,这个设置为true的时候,如果对一个元素进行了操作(put、get),就会把那个元素放到集合的最后,设置为false的时候,无论怎么操作,集合元素的顺序都是按照插入的顺序来进行存储的。

    到了这里我们可以知道,这个LinkedHashmap正是实现Lru算法的核心之处,当内容容量达到最大值的时候,只需要移除这个集合的前面的元素直到集合的容量足够存储数据的时候就可以了。

    相关文章

      网友评论

          本文标题:LruCache

          本文链接:https://www.haomeiwen.com/subject/oleknhtx.html