LRU策略

135 阅读2分钟

LRU(Least Recently Used)是一种常见的缓存淘汰策略。它的核心思想是:当缓存空间不足时,优先淘汰最近最少使用的数据。 具体来说,LRU 策略会维护一个数据结构,用于记录每个数据的访问时间或使用次数。当需要淘汰数据时,LRU 策略会选择访问时间最早或使用次数最少的数据进行淘汰。 实现 LRU 策略的数据结构通常是哈希链表,它结合了哈希表和双向链表的优点。哈希表可以快速查找数据,双向链表可以方便地维护数据的访问顺序。 在实际应用中,LRU 策略常用于缓存系统,如数据库缓存、Web 浏览器缓存等。它可以提高缓存的命中率,减少数据的重复加载,从而提高系统的性能。 以下是使用 Java 实现 LRU 缓存的示例代码:

class LRUCache<K, V> {
   private int capacity;
   private Map<K, Node<K, V>> map;
   private Node<K, V> head;
   private Node<K, V> tail;

   public LRUCache(int capacity) {
       this.capacity = capacity;
       this.map = new HashMap<>();
       this.head = new Node<>();
       this.tail = new Node<>();
       this.head.next = this.tail;
       this.tail.prev = this.head;
   }

   public V get(K key) {
       Node<K, V> node = map.get(key);
       if (node == null) {
           return null;
       }
       removeNode(node);
       addToHead(node);
       return node.value;
   }

   public void put(K key, V value) {
       Node<K, V> node = map.get(key);
       if (node!= null) {
           node.value = value;
           removeNode(node);
           addToHead(node);
           return;
       }

       if (map.size() >= capacity) {
           Node<K, V> removedNode = removeTail();
           map.remove(removedNode.key);
       }

       Node<K, V> newNode = new Node<>(key, value);
       map.put(key, newNode);
       addToHead(newNode);
   }

   private void removeNode(Node<K, V> node) {
       node.prev.next = node.next;
       node.next.prev = node.prev;
   }

   private void addToHead(Node<K, V> node) {
       node.next = head.next;
       node.prev = head;
       head.next.prev = node;
       head.next = node;
   }

   private Node<K, V> removeTail() {
       Node<K, V> removedNode = tail.prev;
       removeNode(removedNode);
       return removedNode;
   }

   private static class Node<K, V> {
       K key;
       V value;
       Node<K, V> prev;
       Node<K, V> next;

       public Node(K key, V value) {
           this.key = key;
           this.value = value;
       }
   }
}

上述代码中,LRUCache类实现了 LRU 缓存。它使用一个哈希表map来存储键值对,同时使用一个双向链表来维护数据的访问顺序。headtail分别表示链表的头节点和尾节点。 get方法用于获取缓存中指定键的值。如果键存在,则将对应节点移动到链表头部,并返回节点的值;否则返回nullput方法用于向缓存中添加或更新键值对。如果键已存在,则更新节点的值,并将其移动到链表头部;否则创建新节点并添加到链表头部。如果缓存已满,则删除链表尾部的节点,并从哈希表中移除对应的键。 通过使用 LRU 策略,可以有效地管理缓存空间,提高缓存的命中率,从而提升系统的性能。具体的实现方式可以根据实际需求进行调整和优化。