基于Java实现本地缓存,缓存过期删除和LRU缓存淘汰

我们结合平常使用的Redis来想下,自己实现本地缓存需要考虑哪些因素呢,我这里总结了三点:

  • 数据存储,基于Java实现的话我首先想到的是key-value结构的集合,如HashMap,并发环境下的话使用ConcurrentHashMap、随着访问顺序元素位置会变化的LinkedHashMap
  • 缓存过期删除策略,参考Redis的定期删除和惰性删除
  • 缓存淘汰策略,有先进先出、最少使用、最近最少使用(LRU)、随机等策略。

由以上可知,

  • 要实现缓存过期删除的话,需要记录元素的生效时间,可以实现一个监控线程或用ScheduledExecutorService实现延迟删除。
  • 缓存淘汰策略采用最近最少使用(LRU)的话,需要维护一个元素的使用队列

实现方式需要涉及的Java类有两种方式:

  • ReentrantLock+ConcurrentHashMap + ConcurrentLinkedQueue
  • ReentrantLock+ LinkedHashMap(本文以这种方式实现)

详细实现代码见下,

public class LocalCache {

    //默认的缓存容量
    private static int DEFAULT_CAPACITY = 16;
    //最大容量
    private static int MAX_CAPACITY = 64;

    private ReentrantLock lock = new ReentrantLock();

    private static Map<String, CacheData> linkedHashM
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java实现LRU缓存淘汰算法的方法与Python类似,也可以使用哈希表和双向链表来实现。下面是一个Java实现LRU缓存淘汰算法的代码示例: ```java class LRUCache { private Map<Integer, Node> map; private int capacity; private Node head; private Node tail; public LRUCache(int capacity) { this.capacity = capacity; map = new HashMap<>(); head = new Node(0, 0); tail = new Node(0, 0); head.next = tail; tail.prev = head; } public int get(int key) { if (map.containsKey(key)) { Node node = map.get(key); remove(node); add(node); return node.value; } else { return -1; } } public void put(int key, int value) { if (map.containsKey(key)) { Node node = map.get(key); node.value = value; remove(node); add(node); } else { if (map.size() == capacity) { Node node = tail.prev; remove(node); map.remove(node.key); } Node node = new Node(key, value); map.put(key, node); add(node); } } private void add(Node node) { Node next = head.next; head.next = node; node.prev = head; node.next = next; next.prev = node; } private void remove(Node node) { Node prev = node.prev; Node next = node.next; prev.next = next; next.prev = prev; } private class Node { int key; int value; Node prev; Node next; public Node(int key, int value) { this.key = key; this.value = value; } } } ``` 在这个实现中,我们同样使用了一个哈希表来查询节点是否存在以及快速删除节点,使用一个双向链表来维护缓存中节点的顺序。当有新的节点被访问时,我们将其移到链表头部,并且当缓存空间不足时,我们淘汰链表尾部的节点。同时,我们使用了一个Node内部类来封装节点的key和value,以及前驱和后继节点的指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值