Java 自定义实现 LRU 缓存算法

背景

LinkedHashMap继承自HashMap,内部提供了一个removeEldestEntry方法,该方法正是实现LRU策略的关键所在,
且HashMap内部专门为LinkedHashMap提供了3个专用回调方法,afterNodeAccess、
afterNodeInsertion、afterNodeRemoval,这3个方法的字面意思非常容易理解,就是节点访问后、节点插入后、节点删除后
分别执行的行为。基于以上行为LinkedHashMap就可以实现一个LRUCache的功能了。

关于LinkedHashMap的eldest:eldest字面意思为最老的,LinkedHashMap中有个叫做accessOrder的字
段,当accessOrder为true时表示LinkedHashMap内部节点按照访问次数排序,最老的节点也就是访问最少的节点。当
accessOrder为false时表示LinkedHashMap内部节点按照插入顺序排序,最老的节点也就是最早插入的节点,该值默认为
false。

实现

自己实现LRUCache只需覆盖removeEldestEntry这个方法即可,代码如下

private static class LRUCache<K, V> extends LinkedHashMap<K, V>
{
  private static final long serialVersionUID = -9111855653176630846L;
  private static int MAX_ELEMENTS;

public LRUCache(int initCap, int maxSize) throws IllegalArgumentException
  {
   super(initCap, 0.75f, true);
   if (maxSize < 0)
    throw new IllegalArgumentException();
   MAX_ELEMENTS = maxSize;
  }

@Override
  protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
  {
   return size() > MAX_ELEMENTS;
  }
}

以上代码需要一个MAX_ELEMENTS变量限制最大存储节点个数,插入节点时判断 如果当

前节点个数已经超过了这个值则会根据LRU策略将访问最少的那个节点删除,这里需要注意,默认LinkedHashMap保证的是插入顺序,也就是节点按

照插入先后来排序的,所以就算删除也是删除最先插入的节点,但是我们在构造函数中传入了一个true,这个参数决定了LinkedHashMap内部的节
点按照什么方式排序,参数为true时说明内部节点按照最近访问的时间排序,为false时说明按照插入顺序排序。至此已完成了一个简易的
LRUCache实现。

注意

由于LinkedHahsMap本身实现不是线程安全的,也就是说这个LRUCache也不是线程安全的,如果想要能多线程访问的话,可以这样使用
它:LRUCache cache = Collections.synchronizedMap(new LRUCache(10,
10))。这样cache就可以在多线程下执行get/put等操作了,但是,用这种方式得到的cache在多线程遍历时还是不安全的。所以不能在多线程
下遍历cache,官方文档也建议在遍历synchronizedmap时使用map本身做同步。

来源:51CTO

时间: 2024-10-03 12:43:26

Java 自定义实现 LRU 缓存算法的相关文章

Java 实现 LRU 缓存的两个实例

Java 自定义实现 LRU 缓存算法 LinkedHashMap继承自HashMap,内部提供了一个removeEldestEntry方法,该方法正是实现LRU策略的关键所在,且HashMap内部专门为LinkedHashMap提供了3个专用回调方法,afterNodeAccess.afterNodeInsertion.afterNodeRemoval,这3个方法的字面意思非常容易理解,就是节点访问后.节点插入后.节点删除后分别执行的行为.基于以上行为LinkedHashMap就可以实现一个L

浅析LRU(K-V)算法缓存教程

LRU(Least Recently Used)算法是缓存技术中的一种常见思想,顾名思义,最近最少使用,也就是说有两个维度来衡量,一个是时间(最近),一个频率(最少).如果需要按优先级来对缓存中的K-V实体进行排序的话,需要考虑这两个维度,在LRU中,最近使用频率最高的排在前面,也可以简单的说最近访问的排在前面.这就是LRU的大体思想. 在操作系统中,LRU是用来进行内存管理的页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU,操作系统会根据哪些数据属于LRU而将其移出内存而腾出空间

缓存、缓存算法(转)

转自http://blog.jobbole.com/30940/ 命中: 当客户发起一个请求(我们说他想要查看一个产品信息),我们的应用接受这个请求,并且如果是在第一次检查缓存的时候,需要去数据库读取产品信息. 如果在缓存中,一个条目通过一个标记被找到了,这个条目就会被使用.我们就叫它缓存命中.所以,命中率也就不难理解了.   Cache Miss: 但是这里需要注意两点: 1. 如果还有缓存的空间,那么,没有命中的对象会被存储到缓存中来. 2. 如果缓存慢了,而又没有命中缓存,那么就会按照某一

Java和Android的LRU缓存及实现原理_Android

一.概述 Android提供了LRUCache类,可以方便的使用它来实现LRU算法的缓存.Java提供了LinkedHashMap,可以用该类很方便的实现LRU算法,Java的LRULinkedHashMap就是直接继承了LinkedHashMap,进行了极少的改动后就可以实现LRU算法. 二.Java的LRU算法 Java的LRU算法的基础是LinkedHashMap,LinkedHashMap继承了HashMap,并且在HashMap的基础上进行了一定的改动,以实现LRU算法. 1.Hash

Java和Android的LRU缓存及实现原理

一.概述 Android提供了LRUCache类,可以方便的使用它来实现LRU算法的缓存.Java提供了LinkedHashMap,可以用该类很方便的实现LRU算法,Java的LRULinkedHashMap就是直接继承了LinkedHashMap,进行了极少的改动后就可以实现LRU算法. 二.Java的LRU算法 Java的LRU算法的基础是LinkedHashMap,LinkedHashMap继承了HashMap,并且在HashMap的基础上进行了一定的改动,以实现LRU算法. 1.Hash

关于LRU缓存的实现算法讨论

业务模型 读.写.删的比例大致是7:3:1,至少要支持500w条缓存,平均每条缓存6k,要求设计一套性能比较好 的缓存算法. 算法分析 不考虑MemCached,Velocity等现成的key-value缓存方案,也不考虑脱离.NET gc自己管理内存,不考 虑随机读取数据及顺序读取数据的场景,目前想到的有如下几种LRU缓存方案 算法 分析 SortedDictionary .NET自带的,内部用二叉搜索树(应该不是普通树,至少是做过优化的树)实现的,检索为O (log n),比普通的Dicti

PreloadDataCache支持预取的数据缓存,使用简单,支持多种缓存算法,支持不同网络类型,扩展性强

主要特性:(1).使用简单 (2).可自动预取新数据 (3).可选择多种缓存算法(包括FIFO.LIFO.LRU.MRU.LFU.MFU等15种)或自定义缓存算法 (4).省流量性能佳(有且仅有一个线程获取数据) (5).支持不同类型网络处理 (6)缓存可序列化到本地 缓存可从文件中恢复 (7).扩展性强 (8). 包含map的大多数接口 适用:Java和Android开发中获取数据较耗时的应用,如网络通讯.响应慢数据获取,在类似网易新闻.花瓣这类应用中可以起到很好的效果.对于图片缓存可直接使用

使用Redis作为一个LRU缓存

原文链接  译者:flychao88 当用Redis作为一个LRU存储时,有些时候是比较方便的,在你增添新的数据时会自动驱逐旧的数据.这种行为在开发者论坛是非常有名的,因为这是流行的memcached系统的默认行为. LRU实际上只是支持驱逐的方式之一.这页包含更多一般的Redis maxmemory指令的话题用于限制内存使用到一个定额,同时它也深入的涵盖了Redis所使用的LRU算法,实际上是精确LRU的近似值. 一.Maxmemory设置指令        Maxmemory设置指令用于配置

java 自定义表格 面板

问题描述 java 自定义表格 面板 如何用java实现一个自定义表格的编写,并将这个表格添加到面板上 解决方案 手把手教你做一个自定义表格标签 博客分类: J2EE 表格自定义标签grid分页table 如果你用公司的平台进行开发的话,许多时候向按钮,输入框,树,菜单等都是直接用一个标签设置几个属性就可以了.全局上样式是统一的,而且容易维护. 之前我已经发使用自定义标签来做数据字典的示例,也就是说自定义标签并不是你想的那么难,今天就再来作一个自定标标签实现的表格控件.当然你别较真,麻雀虽小五脏