• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

浅谈java如何实现Redis的LRU缓存机制

java 搞代码 4年前 (2022-01-05) 29次浏览 已收录 0个评论
文章目录[隐藏]

今天给大家带来的是关于Java的相关知识,文章围绕着java如何实现Redis的LRU缓存机制展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下

LRU概述

最近使用的放在前面,最近没用的放在后面,如果来了一个新的数,此时内存满了,就需要把旧的数淘汰,那为了方便移动数据,肯定就得使用链表类似的数据结构,再加上要判断这条数据是不是最新的或者最旧的那么应该也要使用hashmap等key-value形式的数据结构。

使用LinkedHashMap实现 

 package thread; import java.util.LinkedHashMap; import java.util.Map; public class LRUCacheTest { int capacity; Map map; public <p style="color:transparent">来源gao!daima.com搞$代!码网</p>LRUCacheTest(int capacity){ this.capacity = capacity; map = new LinkedHashMap(); } public int get(int key){ //没有找到 if(!map.containsKey(key)){ return -1; } Integer value = map.remove(key); map.put(key,value); return value; } public void put(int key,int value){ if(map.containsKey(key)){ map.remove(key); map.put(key,value); return; } map.put(key,value); //超出capacity,删除最久没用的即第一个,或者可以复写removeEldestEntry方法 if(map.size() > capacity){ map.remove(map.entrySet().iterator().next().getKey()); } } public static void main(String[] args) { LRUCacheTest lruCache = new LRUCacheTest(10); for (int i = 0; i <10; i++) { lruCache.map.put(i,i); System.out.print(lruCache.map.size()+"\t"); } System.out.println(); System.out.println(lruCache.map); lruCache.put(10,200); System.out.println(lruCache.map); lruCache.put(11,100); System.out.println(lruCache.map); lruCache.get(2); System.out.println(lruCache.map); } } 

结果来看是正确的,距离当前时间最远的数据被淘汰

使用LinkedHashMap简单方法实现

LinkedHashMap是维护了双向链表的HashMap,保持了插入元素的顺序。

LinkedHashMap提供了一个钩子方法,在新插入元素后可以决定是否删除最老的元素。

复写removeEldestEntry实现

 package thread; import java.util.LinkedHashMap; import java.util.Map; public class LRUByLinkedHashMap extends LinkedHashMap { /** * LRU中最大元素数量 */ private int maxSize; public LRUByLinkedHashMap(int maxSize) { // 容量为最大值/0.75,即最大负载容量为maxSize // accessOrder=true  根据查询排序,即最近被使用的放到后面 super((int) Math.ceil(maxSize / 0.75) + 1, 0.75f, true); this.maxSize = maxSize; } /** * 此方法为钩子方法,map插入元素时会调用此方法 * 此方法返回true则证明删除最老的因子 * @param eldest * @return */ @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > maxSize; } public static void main(String[] args) { LRUByLinkedHashMap hashMap = new LRUByLinkedHashMap(10); for (int i = 0; i <10; i++) { hashMap.put(i,i); System.out.print(hashMap.size()+"\t"); } System.out.println(); System.out.println(hashMap); hashMap.put(10,200); System.out.println(hashMap); hashMap.put(11,100); System.out.println(hashMap); hashMap.get(10); System.out.println(hashMap); } } 

双链表+hashmap

 package thread; import java.util.HashMap; import java.util.Map; public class LRURedis { private int capacity; private Map map; private ListNode head; private ListNode tail; public LRURedis(int capacity){ this.capacity = capacity; map = new HashMap(); head = new ListNode(-1,-1); tail = new ListNode(-1,-1); head.next = tail; tail.pre = head; } public int get(int key){ if(!map.containsKey(key)){ return -1; } ListNode node = map.get(key); node.pre.next = node.next; node.next.pre = node.pre; return node.val; } public void put(int key,int value){ if (get(key)!=-1){ map.get(key).val = value; return; } ListNode node = new ListNode(key,value); map.put(key,node); moveToTail(node); if (map.size() > capacity){ map.remove(head.next.key); head.next = head.next.next; head.next.pre = head; } } //把节点移动到尾巴 private void moveToTail(ListNode node) { node.pre = tail.pre; tail.pre = node; node.pre.next = node; node.next = tail; } //定义双向链表节点 private class ListNode{ int key; int val; ListNode pre; ListNode next; //初始化双向链表 public ListNode(int key,int val){ this.key = key; this.val = val; pre = null; next = null; } } } 

以上就是浅谈java如何实现Redis的LRU缓存机制的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:浅谈java如何实现Redis的LRU缓存机制
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址