LRU(Least Recently Used)是一种很常用的资源调度策略,与20/80原则契合,在资源达到上限时倾向保留最近经常访问的资源对象。

Android中基于LRU实现了缓存对象,即LruCache,有两处实现:分别为android.support.v4.util.LruCache和android.util.LruCache,其中前者的设计符合Lru,

后者在资源不足时清除的最近经常访问的资源对象,使用时,需要注意这点,此处分析android.support.v4.util.LruCache的源码。

LruCache是一个范型类,其类图如下:

可以看出LruCache是基于LinkedHashMap的,LinkedHashMap不是线程安全的,所以LruCache通过monitor方式,api上(内)对LruCahce对象

增加synchronized锁实现LruCache的线程安全。LruCache构造函数如下:
                
     
其中0.75表示LinkedHashMap内部的table使用率>=75%时,需要增加table大小,这样hash表的分布会更加均匀,避免向纯链表退化。

其中accessOrder非常重要,若为true,则链表的head->tail的顺序为"最近最少访问->最近经常访问",即当访问某个对象时,会将其插入到tail后,

作为新tail,若accessOrder为false,则在访问时不会移动访问对象的位置。accessOrder=true才符号LruCache的设计要求。

LruCache中的size含义很灵活,LruCache使用者可根据业务需求来定义,比如创建的是一个Bitmap缓存,如LruCache<String, Bitmap>,

这个size可以表示缓存中Bitmap的总大小(单位kb),LruCache提供了计算size的函数,调用者可在LruCache子类中重写来定义,但是需要保持其含义(单位)与

maxSize一致,比如:

下面简要分析下LruCache.get和put,其中get和put都在内部使用map时上锁,get核心代码如下:

可以看到, LruCache是不允许key为null的,当存在key对应的value时,直接返回,此处LinkedHashMap.get操作

会将value挪到tail上,实现如下:

可以看到LinkedHashMap是一个双向循环链表,再来看看put操作:

trimToSize的核心实现如下:

可以看到清理的是head指向的item,即最近最少使用的item,而android.util.LruCache的trimToSize清理的是tail:

总结如下:

1. LRU是一种资源调度策略,倾向清理最近最少访问的资源对象

2.Android中存在两个LruCache,使用support-v4包里的

3.LruCache基于LinkedHashMap的线程安全类,通过锁实现,最近访问的资源对象放到tail是通过LinkedHashMap.get实现

,资源回收是在put中实现。

4.LruCache子类一般需要重写sizeOf,定义缓存中的size

LruCache源码分析的更多相关文章

  1. MyBatis源码分析(3)—— Cache接口以及实现

    @(MyBatis)[Cache] MyBatis源码分析--Cache接口以及实现 Cache接口 MyBatis中的Cache以SPI实现,给需要集成其它Cache或者自定义Cache提供了接口. ...

  2. Volley源码分析(2)----ImageLoader

    一:imageLoader 先来看看如何使用imageloader: public void showImg(View view){ ImageView imageView = (ImageView) ...

  3. druid 源码分析与学习(含详细监控设计思路的彩蛋)(转)

    原文路径:http://herman-liu76.iteye.com/blog/2308563  Druid是阿里巴巴公司的数据库连接池工具,昨天突然想学习一下阿里的druid源码,于是下载下来分析了 ...

  4. Solr4.8.0源码分析(19)之缓存机制(二)

    Solr4.8.0源码分析(19)之缓存机制(二) 前文<Solr4.8.0源码分析(18)之缓存机制(一)>介绍了Solr缓存的生命周期,重点介绍了Solr缓存的warn过程.本节将更深 ...

  5. Solr4.8.0源码分析(18)之缓存机制(一)

    Solr4.8.0源码分析(18)之缓存机制(一) 前文在介绍commit的时候具体介绍了getSearcher()的实现,并提到了Solr的预热warn.那么本文开始将详细来学习下Solr的缓存机制 ...

  6. JDK源码分析(9)之 WeakHashMap 相关

    平时我们使用最多的数据结构肯定是 HashMap,但是在使用的时候我们必须知道每个键值对的生命周期,并且手动清除它:但是如果我们不是很清楚它的生命周期,这时候就比较麻烦:通常有这样几种处理方式: 由一 ...

  7. JDK源码分析(6)之 LinkedHashMap 相关

    LinkedHashMap实质是HashMap+LinkedList,提供了顺序访问的功能:所以在看这篇博客之前最好先看一下我之前的两篇博客,HashMap 相关 和 LinkedList 相关: 一 ...

  8. MyBatis 源码分析系列文章合集

    1.简介 我从七月份开始阅读MyBatis源码,并在随后的40天内陆续更新了7篇文章.起初,我只是打算通过博客的形式进行分享.但在写作的过程中,发现要分析的代码太多,以至于文章篇幅特别大.在这7篇文章 ...

  9. mybatis源码分析(三)------------映射文件的解析

    本篇文章主要讲解映射文件的解析过程 Mapper映射文件有哪几种配置方式呢?看下面的代码: <!-- 映射文件 --> <mappers> <!-- 通过resource ...

随机推荐

  1. 2018.10.16 NOIP模拟 华莱士(并查集)

    传送门 按照题意模拟维护最小的环套树森林就行了. 然而考试的时候naivenaivenaive瞎写了一个错误的贪心. 代码

  2. 2018.09.01 hdu4405 Aeroplane chess (期望dp)

    传送门 期望dp简单题啊. 不过感觉题意不太对. 手过了一遍样例发现如果有捷径必须走. 这样的话就简单了啊. 设f[i]" role="presentation" sty ...

  3. 2018.07.09 洛谷P2365 任务安排(线性dp)

    P2365 任务安排 题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间 ...

  4. 2018.07.06 POJ 1459 Power Network(多源多汇最大流)

    Power Network Time Limit: 2000MS Memory Limit: 32768K Description A power network consists of nodes ...

  5. php PDO mysql

    php PDO写法连接mysql: $db=new PDO("mysql:host=localhost;dbname=sql","root","roo ...

  6. 01-html和head介绍

    一.web标准 web准备介绍: w3c:万维网联盟组织,用来制定web标准的机构(组织) web标准:制作网页遵循的规范 web准备规范的分类:结构标准.表现标准.行为标准. 结构:html.表示: ...

  7. AirplaceLogger源代码解析

    将源代码添加进Eclipse中,右键-->Import-->Existing Projects into Workspace-->选择AirplaceLogger源代码文件夹即可导入 ...

  8. 团队项目第六周——Alpha阶段项目复审(盐酸队)

    Alpha阶段项目复审 小组 优点 缺点,bug报告 名次 天冷记得穿秋裤队 功能比较新颖,可以离线下载,做的比较完整 在下载电影时容易中断 1 只会嘤嘤嘤队 游戏和记单词的融合,也比较新颖 部分浏览 ...

  9. Java对象的serialVersion序列化和反序列化

    Java基础学习总结——Java对象的序列化和反序列化 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种 ...

  10. 阿里巴巴集团2013实习生招聘技术类笔试卷(B)

    一.单选题 1.在常用的网络协议中,___是面向连接的.有重传功能的协议. A.IP   B.TCP    C.UDP    D.DXP 2.500张多米诺骨牌整齐地排成一列,依顺序编号为1.2.3… ...