利用LRUMap 设计缓存
上下文缓存,即将一些常用的数据至于一个缓存集合中,当需要获取这些数据的时候,直接从缓存中读取,而不必每次都从数据库读取,以此提高效率。
其原理类似Apache Commons Collections 项目中LRUMap,LRUMap它继承于AbstractLinkedMap 抽象类,其基本思想是将最近使用的数据放置于双向链表的头上,进行淘汰时只需要删除链表最后一个即可。
继承关系如下图:
从AbstractHashedMap看起,分析AbstractLinkedMap和LURMap。
1、AbstractHashedMap
AbstractHashedMap实现了Map接口,并自己单独实现了Hash算法,使自己成为一个HashedMap。
API介绍如下所示,我只拣几个重要属性和方法介绍一下
http://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/map/AbstractHashedMap.html
2.1属性 protected AbstractHashedMap.HashEntry[] data;
全局数组,每个数组的元素是一个带有后续指针(next)、key、hashcode、hashvalue的数据结构,可以说所有的操作都是为了维护这个数组
2.2属性 protected static int DEFAULT_CAPACITY
默认的数组大小,可以通过构造函数指定
2.3属性 protected float loadFactor
扩展因子,默认为0.75,即数组填充率达到数组大小的75%的时候,会默认调整大小,重新计算元素在数组中的位置。
2.4方法 java.lang.Object get(java.lang.Object key)
从data[]中与链表结构中取得value
2.5方法 java.lang.Object put(java.lang.Object key, java.lang.Object value)
首先查看该value是否在data[]中,如果存在就更新一下就完事;否则就调用addMapping方法,生成一个新的HashEntry结构,加入到data[hashcode]对应位置的链表头上。在addMapping方法中,会检查容量是否超出了大小,如果查出了限制,则将容量扩大一倍,同时重新将所有数据塞进去。
2.6方法 java.lang.Object remove(java.lang.Object key)
从维护的data结构中删除对应的value
2.7方法 protected void reuseEntry(AbstractHashedMap.HashEntry entry, int hashIndex, int hashCode, java.lang.Object key, java.lang.Object value)
未研究
2.7其他方法,作用见名知意
protected void addEntry(AbstractHashedMap.HashEntry entry, int hashIndex)
protected void addMapping(int hashIndex, int hashCode, java.lang.Object key, java.lang.Object value)
protected void removeEntry(AbstractHashedMap.HashEntry entry, int hashIndex, AbstractHashedMap.HashEntry previous)
protected void removeMapping(AbstractHashedMap.HashEntry entry, int hashIndex, AbstractHashedMap.HashEntry previous)
2、AbstractLinkedMap
AbstractLinkedMap继承自前面的AbstractHashedMap,在AbstractHashedMap的基础上,将所有的HashEntity维护成双向的链表
API地址如下:
http://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/map/LinkedMap.html
3.1属性 protected AbstractLinkedMap.LinkEntry header
LinkEntry继承自HashEntry,又额外包含了before、after两个指针,形成双向链表
3.2方法 protected void addEntry(AbstractHashedMap.HashEntry entry, int hashIndex)重写了父类的增加节点的方法,不但维护data[],同时维护了双向链表
3.3方法 protected void removeEntry(AbstractHashedMap.HashEntry entry, int hashIndex, AbstractHashedMap.HashEntry previous)重写了父类的删除节点的方法,不但维护了data[],同时维护了双向链表
3、LRUMap
LRUMap也是非线程安全。主要是在父类AbstractLinedMap的基础上,在更新双向链表的时候增加了moveToMRU/removeLRU操作
4.1方法 protected void moveToMRU(AbstractLinkedMap.LinkEntry entry)
将entry移动到双向链表的头部
4.2方法 protected boolean removeLRU(AbstractLinkedMap.LinkEntry entry)
从双向链表中移除
4.3方法 protected void reuseMapping(AbstractLinkedMap.LinkEntry entry, int hashIndex, int hashCode, java.lang.Object key, java.lang.Object value)重写父类的方法
4、扩展
利用LRUMap实现上下文缓存,可以对原有的LRUMap进行的改造点
(1)重写了LRUMAP类,采用synchronized关键字实现了线程级别安全。
(2)增加了对缓存数据容量的控制,超过容量之后,从双向链表中将最后使用的Entity从链表中删除。
(3)缓存数据的更新,采用异步通知机制,一旦受到更新通知,将变更的数据从换从中清除
参考:
http://annegu.iteye.com/blog/539465
http://www.blogjava.net/xmatthew/archive/2012/06/28/380150.html
利用LRUMap 设计缓存的更多相关文章
- 利用MVVM设计快速开发个人中心、设置等模块
我们在做iOS开发过程中,静态页面的开发比开发动态页面更让我们开发者抓狂.因为动态页面通常是一个页面一种cell样式,作为开发者只需要专注于定制好一种样式之后,就可以使用数据填充出较好的界面.而静态c ...
- 利用PYTHON设计计算器功能
通过利用PYTHON 设计处理计算器的功能如: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))- (-4*3 ...
- 利用单例模式设计数据库连接Model类
之前在<[php]利用php的构造函数与析构函数编写Mysql数据库查询类>(点击打开链接)写过的Mysql数据库查询类还不够完美,利用<[Java]单例模式>(点击打开链接) ...
- 【CPU微架构设计】利用Verilog设计基于饱和计数器和BTB的分支预测器
在基于流水线(pipeline)的微处理器中,分支预测单元(Branch Predictor Unit)是一个重要的功能部件,它负责收集和分析分支/跳转指令的执行结果,当处理后续分支/跳转指令时,BP ...
- 2017-4-25/设计缓存(LFU)
1. 恒定缓存性能有哪些因素? 命中率.缓存更新策略.缓存最大数据量. 命中率:指请求缓存次数和缓存返回正确结果次数的比例.比例越高,缓存的使用率越高,用来衡量缓存机智的好坏和效率.如果数据频繁更新, ...
- UE4笔记:利用Widget设计一个切换材质功能
UE4引擎中的Widget蓝图是一个重要的工具,可用于场景中的页面叠加,镜头绑定,场景切换等多处地方,在这里笔者介绍一种利用控件蓝图和场景中物体进行信息交互的方法,直观的体现就是进行物体的材质切换. ...
- iOS利用SDWebImage实现缓存的计算与清理
概述 可以仅仅清理图片缓存, 也可以清理所有的缓存文件(包括图片.视频.音频等). 详细 代码下载:http://www.demodashi.com/demo/10717.html 一般我们项目中的缓 ...
- PyQt5系列教程(二)利用QtDesigner设计UI界面
软硬件环境 OS X EI Capitan Python 3.5.1 PyQt 5.5.1 PyCharm 5.0.1 前言 在PyQt5系列教程的第一篇http://blog.csdn.net/dj ...
- 利用PowerDesigner设计数据库
PowerDesigner非常强大, 可以利用它完成数据库的设计. 1.下载地址:http://pan.baidu.com/s/1DsLrg 2.表设计: 建立概念数据模型(Conceptual Da ...
随机推荐
- Android 滑动效果入门篇(二)—— Gallery
Gallery 是Android官方提供的一个View容器类,继承于AbsSpinner类,用于实现页面滑动效果. 从上面的继承关系可以看出,AbsSpinner类继承自AdapterView,因此我 ...
- 出错处理完美搭配之perror&exit
对于库函数出错处理有两个十分有用的函数perror和exit: 一.错误报告 perror函数用一种简单统一的方式报告错误.ANSI C中的许多库函数,尤其是I/O函数,会调用操作系统去执行一些工作. ...
- 在Linux使用mingw32来编写win32程序
MinGW - Minimalist GNU For Windows Mingw32 是 GNU 計畫工具的集合,包含了大量的標頭檔(header files).函式庫與指 令程式.目的在提供免費的工 ...
- 小米2s使用Hexamob Recovery PRO恢复数据
这东西对于手机来说, 真是神器啊 现在很多手机都是以MTP连接到电脑的, 所以在PC上是看不到盘符, 也就无法使用finaldata 之类的工具恢复了. 而像小米2S这样的手机, 无法外接SD卡, 则 ...
- 深入理解 GCD
前言 首先提出一些问题: dispatch_async 函数如何实现,分发到主队列和全局队列有什么区别,一定会新建线程执行任务么? dispatch_sync 函数如何实现,为什么说 GCD 死锁是队 ...
- 由c#的值类型与引用类型说开去
之前一直被灌输,C#分值类型和引用类型,在程序运行时,它们分别存在栈(Stack) 和堆(Heap)上.这也是面试经典问题了,但其实其中存在很大的误解.比如某个实例对象中有一个Int型成员.当这个实例 ...
- python--json & pickle 模块
用于序列化的两个模块 json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 Json模块提供了四个功能:dumps. ...
- sed程序
程序1: 实现简单的shell sed替换功能 程序2:修改haproxy配置文件 1.查 输入:www.oldboy.org 获取当前backend下的所有记录 2.新建 输入: arg = { ...
- 给jdk写注释系列之jdk1.6容器(5)-LinkedHashMap源码解析
前面分析了HashMap的实现,我们知道其底层数据存储是一个hash表(数组+单向链表).接下来我们看一下另一个LinkedHashMap,它是HashMap的一个子类,他在HashMap的基础上维持 ...
- 集群服务器Session同步
事实上,网站总是有状态的.每一个登录信息.用户信息常常被存储在session内部.而当一个网站被部署在不止一台服务器的时候,就会遇到session同步的问题.事实上即使一个很小的网站,也要至少有两台服 ...