Android LruCache类分析
public class LurCache<K, V> {
private final LinkedHashMap<K, V> map;
private int size; // 已经存储的大小
private int maxSize; // 规定的最大存储空间
private int putCount; // put的次数
private int createCount; // create的次数
private int evictionCount; // 回收的次数
private int hitCount; // 命中的次数
private int missCount; // 丢失的次数
public LruCache(int maxSize) {
if (maxSize <= ) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap<K, V>(, 0.75f, true);
}
public final V get(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}
V mapValue;
synchronized (this) {
mapValue = map.get(key);
if (mapValue != null) {
hitCount++; // 命中
return mapValue;
}
missCount++; // 丢失
}
V createdValue = create(key);
if (createdValue == null) {
return null;
}
synchronized (this) {
createCount++;// 创建++
mapValue = map.put(key, createdValue);
if (mapValue != null) {
// There was a conflict so undo that last put
// 如果前面存在oldValue,那么撤销put()
map.put(key, mapValue);
} else {
size += safeSizeOf(key, createdValue);
}
}
if (mapValue != null) {
entryRemoved(false, key, createdValue, mapValue);
return mapValue;
} else {
trimToSize(maxSize);
return createdValue;
}
}
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) { //返回的先前的value值
size -= safeSizeOf(key, previous);
}
}
if (previous != null) {
entryRemoved(false, key, previous, value);
}
trimToSize(maxSize);
return previous;
}
//清空cache空间
private void trimToSize(int maxSize) {
while (true) {
K key;
V value;
synchronized (this) {
if (size < || (map.isEmpty() && size != )) {
throw new IllegalStateException(getClass().getName()
+ ".sizeOf() is reporting inconsistent results!");
}
if (size <= maxSize) {
break;
}
Map.Entry<K, V> toEvict = map.entrySet().iterator().next();
if (toEvict == null) {
break;
}
key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key);
size -= safeSizeOf(key, value);
evictionCount++;
}
entryRemoved(true, key, value, null);
}
}
//删除key相应的cache项,返回相应的value
public final V remove(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}
V previous;
synchronized (this) {
previous = map.remove(key);
if (previous != null) {
size -= safeSizeOf(key, previous);
}
}
if (previous != null) {
entryRemoved(false, key, previous, null);
}
return previous;
}
//当item被回收或者删掉时调用。该方法当value被回收释放存储空间时被remove调用, 或者替换item值时put调用,默认实现什么都没做。
//true: 为释放空间被删除;false: put或remove导致
protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}
protected V create(K key) {
return null;
}
private int safeSizeOf(K key, V value) {
int result = sizeOf(key, value);
if (result < ) {
throw new IllegalStateException("Negative size: " + key + "=" + value);
}
return result;
}
protected int sizeOf(K key, V value) {
return ;
}
//清空cache
public final void evictAll() {
trimToSize(-); // -1 will evict 0-sized elements
}
public synchronized final int size() {
return size;
}
public synchronized final int maxSize() {
return maxSize;
}
public synchronized final int hitCount() {
return hitCount;
}
public synchronized final int missCount() {
return missCount;
}
public synchronized final int createCount() {
return createCount;
}
public synchronized final int putCount() {
return putCount;
}
//返回被回收的数量
public synchronized final int evictionCount() {
return evictionCount;
}
//返回当前cache的副本,从最近最少访问到最多访问
public synchronized final Map<K, V> snapshot() {
return new LinkedHashMap<K, V>(map);
}
public synchronized final String toString() {
int accesses = hitCount + missCount;
int hitPercent = accesses != ? ( * hitCount / accesses) : ;
return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
maxSize, hitCount, missCount, hitPercent);
}
}
Android LruCache类分析的更多相关文章
- Android LayoutInflater 类分析
作为一名Android开发者,写页面是最普通不过的事情了,在编写页面的时候,系统给提供了两种形式,一种形式是通过XML的方式进行编写,还有一种形式是通过Java代码直接编写 我们知道Android ...
- Android LRUCache简介
LRU Cache数据结构的介绍可以参考前面的http://www.cnblogs.com/XP-Lee/p/3441555.html. 本文以Android LRUCache来做一个简单的介绍.我们 ...
- Android的消息循环机制 Looper Handler类分析
Android的消息循环机制 Looper Handler类分析 Looper类说明 Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...
- 「Android」消息驱动Looper和Handler类分析
Android系统中的消息驱动工作原理: 1.有一个消息队列,可以往这个消息队列中投递消息; 2.有一个消息循环,不断的从消息队列中取得消息,然后处理. 工作流程: 1.事件源将待处理的消息加入到消息 ...
- 源码分析篇 - Android绘制流程(三)requestLayout()与invalidate()流程及Choroegrapher类分析
本文主要探讨能够触发performTraversals()执行的invalidate().postInvalidate()和requestLayout()方法的流程.在调用这三个方法到最后执行到per ...
- Android APP性能分析方法及工具
近期读到<Speed up your app>一文.这是一篇关于Android APP性能分析.优化的文章.在这篇文章中,作者介绍他的APP分析优化规则.使用的工具和方法.我觉得值得大家借 ...
- Android源码分析-全面理解Context
前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...
- Android 服务类Service 的详细学习
http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有 ...
- cocos2d-x for android:SimpleGame分析
cocos2d-x for android:SimpleGame分析 作为cocos2d-x的标配DEMO,SimpleGame可算是给入门学cocos2d-x的俺们这些新手门学习的对象了,那么来分析 ...
随机推荐
- Java读取txt文件和覆盖写入txt文件和追加写入txt
//创建文件 public static void createFile(File filename) { try { if(!filename.exists()) { filename.create ...
- 使用iVMS-4200 存储录像数据时的设置
1.安装软件时,选择:存储服务器 2.对存储服务器进行配置,具体配置见 配置手册.
- 编程里的API是什么意思?
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码 ...
- ListView常用操作
1.设置ListView只显示一列,并且每加一条记录是向下添加的. ListView添加方法:把View属性改成Details,再Columns属性中添加一列 然后用如下代码即可实现 ListView ...
- qwt的安装和移植-
目须要依据实时数据绘制出图表,因此我们找到了qwt库.这个库是一个绘制图表,曲线图,柱状图的统计图标. . .. 以下我们就具体解说一下这个库在Larm上的编译和移植 qwt介绍 QWT,全称是Qt ...
- js---05 自定义属性
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- js---03属性操作
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- Razor数组数据
控制器层 public ActionResult DemoArray() { Product[] array = { new Product {Name = "Kayak", Pr ...
- css+ js 实现圆环时钟
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 2017-百度之星 初赛-B
1001 Chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...