上下文缓存,即将一些常用的数据至于一个缓存集合中,当需要获取这些数据的时候,直接从缓存中读取,而不必每次都从数据库读取,以此提高效率。

其原理类似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 设计缓存的更多相关文章

  1. 利用MVVM设计快速开发个人中心、设置等模块

    我们在做iOS开发过程中,静态页面的开发比开发动态页面更让我们开发者抓狂.因为动态页面通常是一个页面一种cell样式,作为开发者只需要专注于定制好一种样式之后,就可以使用数据填充出较好的界面.而静态c ...

  2. 利用PYTHON设计计算器功能

    通过利用PYTHON 设计处理计算器的功能如: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))- (-4*3 ...

  3. 利用单例模式设计数据库连接Model类

    之前在<[php]利用php的构造函数与析构函数编写Mysql数据库查询类>(点击打开链接)写过的Mysql数据库查询类还不够完美,利用<[Java]单例模式>(点击打开链接) ...

  4. 【CPU微架构设计】利用Verilog设计基于饱和计数器和BTB的分支预测器

    在基于流水线(pipeline)的微处理器中,分支预测单元(Branch Predictor Unit)是一个重要的功能部件,它负责收集和分析分支/跳转指令的执行结果,当处理后续分支/跳转指令时,BP ...

  5. 2017-4-25/设计缓存(LFU)

    1. 恒定缓存性能有哪些因素? 命中率.缓存更新策略.缓存最大数据量. 命中率:指请求缓存次数和缓存返回正确结果次数的比例.比例越高,缓存的使用率越高,用来衡量缓存机智的好坏和效率.如果数据频繁更新, ...

  6. UE4笔记:利用Widget设计一个切换材质功能

    UE4引擎中的Widget蓝图是一个重要的工具,可用于场景中的页面叠加,镜头绑定,场景切换等多处地方,在这里笔者介绍一种利用控件蓝图和场景中物体进行信息交互的方法,直观的体现就是进行物体的材质切换. ...

  7. iOS利用SDWebImage实现缓存的计算与清理

    概述 可以仅仅清理图片缓存, 也可以清理所有的缓存文件(包括图片.视频.音频等). 详细 代码下载:http://www.demodashi.com/demo/10717.html 一般我们项目中的缓 ...

  8. 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 ...

  9. 利用PowerDesigner设计数据库

    PowerDesigner非常强大, 可以利用它完成数据库的设计. 1.下载地址:http://pan.baidu.com/s/1DsLrg 2.表设计: 建立概念数据模型(Conceptual Da ...

随机推荐

  1. iOS开发——面试总结(一)

    面试总结(一) 通过网络搜寻和自己总结经历找了一些IOS面试经常被问道的问题: 1.搞清楚touch事件的传递(事件的响应链) 事件的响应(responder chain) 只有继承了UIRespon ...

  2. 首发Zend Studio 10.6正式版注册破解(2014-02-06更新)

    1.写在前头以下文章没有图片说明,如果你没有耐性看或想看图文并茂的图片文章请绕道,谢谢配合.转发请标明转自http://www.geekso.com/ZendStudio100/以下方法仅供技术交流学 ...

  3. [Effective C++ --033]避免遮掩继承而来的名称

    这一章一直在想怎么写,因为比较基础,很容易理解,就按照需要来写吧. 假设我们有这样一个类: class Base { private: int x; public: ; virtual void mf ...

  4. 描述cookie,sessionstroage,localstrage的区别

    HTML5 提供了两种在客户端存储数据的新方法(Web Storage): localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 ...

  5. 实例源码--Android小工具源码

      下载源码   技术要点: 1. Android控件布局的使用 2. Http通信 3. XML数据解析 4. 网络状态的监听 5. 源码带有非常详细的中文注释 ...... 详细介绍: 1. An ...

  6. PHP 正则表达式语法

    则表达式简介 在某些应用中,往往有时候需要根据一定的规则来匹配(查找)确认一些字符串,如要求用户输入的 QQ 号码为数字且至少 5 位.用于描述这些规则的工具就是正则表达式. 最简单的匹配 最简单的匹 ...

  7. Redis 有序集合(sorted set)

    Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分数来为集合中的成员进行从小到大的排序. 有序 ...

  8. org.apache.hadoop.fs-BufferedFSInputStream

    封装了FSInputStream package org.apache.hadoop.fs; import java.io.BufferedInputStream; import java.io.IO ...

  9. df 和 du 命令详解

    df命令详细用法 a:显示全部的档案系统和各分割区的磁盘使用情形 i:显示i -nodes的使用量 k:大小用k来表示 (默认值) t:显示某一个档案系统的所有分割区磁盘使用量 x:显示不是某一个档案 ...

  10. jQuery中利用JSONP解决AJAX跨域问题

    写在前面 跨域的解决方案有多种,其中最常见的是使用同一服务器下的代理来获取远端数据,再通过ajax进行读取,而在这期间经过了两次请求过程,使得获取数据的效率大大降低,这篇文章蓝飞就为大家介绍一下解决跨 ...