利用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 ...
随机推荐
- 第1章 游戏之乐——NIM(1)一排石子的游戏
NIM(1)一排石子的游戏 转载:编程之美-MIN(1)一排石头的游戏 1. 原题 1.1 题目 N块石头排成一行,每块石头有各自固定的位置.两个玩家依次取石头,每个玩家每次可以取其中任意一块石头,或 ...
- C#_在.net中序列化读写xml方法的总结
阅读目录 开始 最简单的使用XML的方法 类型定义与XML结构的映射 使用 XmlElement 使用 XmlAttribute 使用 InnerText 重命名节点名称 列表和数组的序列化 列表和数 ...
- 在 CentOS 中编译安装 VIM 7.3
转载:http://blog.csdn.net/zhanglyung/article/details/6204574 默认安装的 Vim 不带有多字符支持,所以不支持中文.无论是将 CentOS 本来 ...
- Spring 中jdbcTemplate 实现执行多条sql语句
说一下Spring框架中使用jdbcTemplate实现多条sql语句的执行: 很多情况下我们需要处理一件事情的时候需要对多个表执行多个sql语句,比如淘宝下单时,我们确认付款时要对自己银行账户的表里 ...
- IIS错误500.21
操作系统:win7,有.net2.0,.net4.0 网站4.5, 错误原因:IIS未注册4.0框架. 解决办法: %windir%\Microsoft.NET\Framework\v4.0.3031 ...
- wpf 父控件透明子控件不透明
在wpf开发中遇到子控件会继承父类控件属性的问题, 例如: <StackPanel Orientation="Horizontal" Grid.Row="1&quo ...
- MySQL多实例配置
实验环境:RHEL6.4为最小化安装,mysql安装包为通用二进制安装包,版本为mysql-5.6.26 创建mysql用户 #useradd –M –s /sbin/nologin mysql #y ...
- ip 子网掩码 网关 DNS
这一篇文章也很好: 原文引用于: http://www.cnblogs.com/jiqing9006/p/3365939.html 内外网ip: IP地址: IPv4地址分为A.B.C.D.E五类, ...
- 利用SCI做的一个足球答题系统
SCI,异步串行通信接口,内置独立的波特率产生电路和SCI收发器,可以选择发送8或9个数据位(其中一位可以指定为奇或偶校验位). SCI是全双工异步串行通信接口,主要用于MCU与其他计算机或设备之间的 ...
- 【分割圆】Uva 10213 - How Many Pieces of Land ?
一个椭圆上有N个点,将这n个点两两相连,问最多能将这个椭圆分成多少片. 理清思路,慢慢推. 首先我们要想到欧拉公式:V+E-F=2 其中V为图上的顶点数,E为边数,F为平面数. 计算时的可以枚举点,从 ...