android开发LruCache原理理解与源码实现方式
-
LRU原理:
- 简写:Least Recently Used
- 即最近最少使用,是一种调度算法或者说淘汰机制。就是每个Item都有一个访问字段t,记录自上次被访问的时间,当需要移除时选择移除t值最大的Item。
-
androidx.collection.LruCache实现
- 基层依赖LinkedHashMap。而LinkedHashMap是一个双向链表。
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); } //accessOrder为false,表示map元素顺序跟随插入顺序,默认值。 //accessOrder为true,表示map元素顺序跟随访问顺序变化。即一个元素被访问时,同时调整其位置将其放到最后,刚好符合lru原则。
- put方法
public final V put(@NonNull K key, @NonNull V value) { V previous; synchronized (this) {//线程安全的 size += safeSizeOf(key, value); //在key位置上放新值value,返回key位置之前的旧值 previous = map.put(key, value); if (previous != null) {//减去旧值的size size -= safeSizeOf(key, previous); } } //如果旧值不为空,则回调entryRemoved方法 if (previous != null) { entryRemoved(false, key, previous, value); } trimToSize(maxSize);//size变化了,检查要不要剔除最老元素 return previous; }
- get方法
public final V get(@NonNull K key) { V mapValue; synchronized (this) { //注意:get方法不仅取值,如果取到了还会更新该元素位置 //即移到链表最后位置tail,因为之前参数accessOrder为true mapValue = map.get(key); if (mapValue != null) { return mapValue;//找到了直接返回 } } V createdValue = create(key);//找不到就创建新的 if (createdValue == null) { return null; } synchronized (this) { mapValue = map.put(key, createdValue); if (mapValue != null) {//基本为null,除非并发 map.put(key, mapValue); } else {//size变化,后面调用trimToSize重新检查调整 size += safeSizeOf(key, createdValue); } } if (mapValue != null) {//并发导致刚好已经有旧值了 entryRemoved(false, key, createdValue, mapValue); return mapValue; } else { trimToSize(maxSize); return createdValue; } }
- trimToSize方法
public void trimToSize(int maxSize) { while (true) { K key; V value; synchronized (this) { //如果size没有达到最大缓存maxSize或者map为空,直接返回了,不需要移除操作 if (size <= maxSize || map.isEmpty()) { break; } //获取第一个元素,也就是最老最久没被使用的元素,将它移除。还记得get时会刷新get到元素的位置吧?? Map.Entry<K, V> toEvict = map.entrySet().iterator().next(); key = toEvict.getKey(); value = toEvict.getValue(); map.remove(key); size -= safeSizeOf(key, value);//移除后size减少 } entryRemoved(true, key, value, null); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2017-07-13 常用的好用的window工具
2017-07-13 配置java jdk环境变量