使用LinkedHashMap实现LRU缓存

标签: Java | 发表时间:2015-09-07 09:17 | 作者:
出处:http://colobu.com/

可能很多人已经知道了这个技术,但是对于我来说,虽然使用Java十余年了,最近才了解到 LinkedHashMap这个类。使用这个类可以方便的实现一个本地的LRU Cache类。

之所以没有关注到这个类,是因为在面对本地缓存的case时,我经常会考虑 guava这个框架。
最早可以搜到的一篇关于 LinkedHashMap实现本地缓存的文章之一是这篇: How to set up a simple LRU cache using LinkedHashMap ,发表于2005年。文末有附了几篇关于 LinkedHashMap类的介绍。

这个类实现了Hash和双向链表两种数据结构的混合。 所以通过 get方法可以很快的得到相应的元素,而链表结构又可以根据 access或者 insert进行排序。但是这种
方式也会有性能的损耗,因为对数据的插入需要同时更新这两个数据结构,对数据的访问在 accessOrder情况下也会涉及数据的移动。 我们知道数据量大的情况下对链表的更改是很耗时的,所以使用的时候要仔细考量。

好了,下面就是一个local cache的实现,抄自 A LRU Cache in 10 Lines of Java

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     
import java.util.LinkedHashMap;
import java.util.Map;
public LRUCache<K, V> extends LinkedHashMap<K, V> {
private int cacheSize;
public LRUCache(int cacheSize) {
super(16, 0.75, true);
this.cacheSize = cacheSize;
}
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() >= cacheSize;
}
}

主要实现 removeEldestEntry方法,这个方法如果返回true,则会移除最老的数据。这只会在调用 put或者 putAll时发生。

很重要的一点, 此类不是线程安全的,所以使用的时候你需要加锁。

参考文档

  1. A LRU Cache in 10 Lines of Java
  2. How to set up a simple LRU cache using LinkedHashMap
  3. LinkedHashMap as LRU cache
  4. https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html

相关 [linkedhashmap lru 缓存] 推荐:

使用LinkedHashMap实现LRU缓存

- - 鸟窝
可能很多人已经知道了这个技术,但是对于我来说,虽然使用Java十余年了,最近才了解到 LinkedHashMap这个类. 使用这个类可以方便的实现一个本地的LRU Cache类. 之所以没有关注到这个类,是因为在面对本地缓存的case时,我经常会考虑 guava这个框架. 最早可以搜到的一篇关于 LinkedHashMap实现本地缓存的文章之一是这篇: How to set up a simple LRU cache using LinkedHashMap ,发表于2005年.

使用Redis作为一个LRU缓存

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

Memcached的LRU算法

- Eric - 平凡的世界
最近计划对Memcached做一些尝试性的改造,主要是针对Memcached在处理过期数据的时候进行改造,以实现在一个缓存的过期时间达到的时候,可以对该缓存的数据进行一个验证和存储的处理. 这个需求,主要是为了解决MySQL的写入瓶颈,通过延期、合并写入请求来减少MySQL的并发写入量. 现在逐渐记录出来和有需要的朋友一起讨论.

400行代码实现本地Key-Value缓存,性能每秒几百万次,进程重启有效,LRU淘汰——HashTable

- - CSDN博客数据库推荐文章
liuyun827@foxmail.com原创,转载请注明出处: http://blog.csdn.net/gdutliuyun827. Key-Value缓存有很多,用的较多的是memcache、redis,他们都是以独立服务的形式运行,在工作中有时需要嵌入一个本地的key-value缓存,当然已经有LevelDb等,但感觉还是太重量级了.

缓存算法

- lostsnow - 小彰
没有人能说清哪种缓存算法由于其他的缓存算法. (以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下  ). 大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率. 我是LRU缓存算法,我把最近最少使用的缓存对象给踢走. 我总是需要去了解在什么时候,用了哪个缓存对象.

Hibernate 缓存

- - ITeye博客
1数据缓存:(date caching) 是一种将数据暂时存于内存缓存去中的技术,缓存通常是影响系统性能的关键因素. 2.ORM的数据缓存策略有3中.   1.事务级缓存:  分为 数据库事务和 应用级事务,是基于Session的生命周期的实现,每个session都会在内部维持一个数据缓存, 随session的创建和消亡.

hibernate缓存,一级缓存,二级缓存,查询缓存

- - CSDN博客推荐文章
1、缓存是数据库数据在内存中的临时容器,它包含了库表数据在内存中的临时拷贝,位于数据库和访问层之间. 2、ORM在进行数据读取时,会根据缓存管理策略,首先在缓冲中查询,如果发现,则直接使用,避免数据库调用的开销. 事务级缓存:当前事务范围内的数据缓存. 应用级缓存:某个应用中的数据缓存. 分布式缓存:多个应用,多个JVM之间共享缓存.

缓存相关——缓存穿透、缓存并发、缓存失效、缓存预热、缓存雪崩、缓存算法

- - 编程语言 - ITeye博客
我们在项目中使用缓存通常都是先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回. 这个时候如果我们查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB,这样缓存就失去了意义,在流量大时,可能DB就挂掉了. 要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞.

Hibernate 二级缓存

- - CSDN博客推荐文章
很多人对二级缓存都不太了解,或者是有错误的认识,我一直想写一篇文章介绍一下hibernate的二级缓存的,今天终于忍不住了. 我的经验主要来自hibernate2.1版本,基本原理和3.0、3.1是一样的,请原谅我的顽固不化. hibernate的session提供了一级缓存,每个session,对同一个id进行两次load,不会发送两条sql给数据库,但是session关闭的时候,一级缓存就失效了.