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

目录

  • LRU概述
  • 使用LinkedHashMap实现
  • 使用LinkedHashMap简单方法实现
  • 双链表+hashmap

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

使用LinkedHashMap实现
package thread; import java.util.LinkedHashMap; import java.util.Map; public class LRUCacheTest {int capacity; Map map; public LRUCacheTest(int capacity){this.capacity = capacity; map = new LinkedHashMap<>(); } public int get(int key){//没有找到if(!map.containsKey(key)){return -1; }Integer value = https://www.it610.com/article/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); } }

浅谈java如何实现Redis的LRU缓存机制
文章图片

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

使用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*/@Overrideprotected 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); } }

浅谈java如何实现Redis的LRU缓存机制
文章图片

【浅谈java如何实现Redis的LRU缓存机制】
双链表+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缓存机制的文章就介绍到这了,更多相关java实现Redis的LRU缓存机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读