Java手动实现Redis的LRU缓存机制

作者:拉霍拉卡 时间:2023-07-31 12:51:30 

前言

最近在逛博客的时候看到了有关Redis方面的面试题,其中提到了Redis在内存达到最大限制的时候会使用LRU等淘汰机制,然后找了这方面的一些资料与大家分享一下。 LRU总体大概是这样的,最近使用的放在前面,最近没用的放在后面,如果来了一个新的数,此时内存满了,就需要把旧的数淘汰,那为了方便移动数据,肯定就得使用链表类似的数据结构,再加上要判断这条数据是不是最新的或者最旧的那么应该也要使用hashmap等key-value形式的数据结构。

第一种实现(使用LinkedHashMap)


public class LRUCache {
int capacity;
   Map<Integer,Integer> map;
public LRUCache(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) {
       LRUCache lruCache = new LRUCache(10);
       for (int i = 0; i < 10; i++) {
           lruCache.map.put(i,i);
           System.out.println(lruCache.map.size());
       }
       System.out.println(lruCache.map);
       lruCache.put(10,200);
       System.out.println(lruCache.map);
   }

Java手动实现Redis的LRU缓存机制

第二种实现(双链表+hashmap)


public class LRUCache {
private int capacity;
   private Map<Integer,ListNode>map;
   private ListNode head;
   private ListNode tail;
public LRUCache2(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;
       }
   }
}

补充

像第一种方式,如果复写removeEldestEntry会更简单,这里简单的展示一下


public class LRUCache extends LinkedHashMap<Integer,Integer> {
private int capacity;
@Override
   protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
       return size() > capacity;
   }
}

来源:https://blog.csdn.net/Grady00/article/details/115168822

标签:Java,LRU,redis
0
投稿

猜你喜欢

  • Android中Blade的使用方法

    2023-04-25 11:29:54
  • spring定时任务执行两次及tomcat部署缓慢问题的解决方法

    2022-12-27 09:53:25
  • java 同步、异步、阻塞和非阻塞分析

    2022-08-09 03:02:42
  • Java编写日历表的3种方式

    2023-02-16 00:50:31
  • c#中值类型和引用类型的基础教程

    2021-10-20 18:03:41
  • JAVA SFTP文件上传、下载及批量下载实例

    2023-02-11 14:31:46
  • java 集合----Map、Collection

    2022-11-09 03:39:01
  • Spring Bean的线程安全问题

    2023-06-07 17:15:36
  • Android实现环形进度条代码

    2023-06-08 11:09:55
  • 探讨:将两个链表非降序合并为一个链表并依然有序的实现方法

    2023-06-23 01:41:38
  • Java解码H264格式视频流中的图片

    2023-11-24 23:58:24
  • Springboot Websocket Stomp 消息订阅推送

    2022-05-08 14:39:30
  • Kotlin协程launch启动流程原理详解

    2021-10-31 15:47:22
  • 详解使用IntelliJ IDEA新建Java Web后端resfulAPI模板

    2023-12-14 09:26:04
  • Android使用TextView,设置onClick属性无效的解决方法

    2022-06-27 11:32:39
  • C#使用RabbitMq队列(Sample,Work,Fanout,Direct等模式的简单使用)

    2023-12-06 10:45:34
  • Gradle的缓存路径修改的四种方法(小结)

    2021-11-09 11:05:51
  • 详解JAVA 强引用

    2021-11-06 18:38:16
  • C++集体数据交换实现示例讲解

    2023-12-17 11:35:07
  • java中functional interface的分类和使用详解

    2021-09-15 15:59:20
  • asp之家 软件编程 m.aspxhome.com