lru算法

LRU全称Least Recently Used,也就是最近最少使用的意思,是一种内存管理算法,最早应用于Linux系统。

LRU算法基于一种假设,长期不使用的数据,在未来的使用性也不大。因此,当数据占用内存达到一定的阙值时,我们要移除最近最少使用的数据。

LRU算法中,使用了一种有趣的数据结构,叫做哈希链表。

我们都知道,哈希表是由若干个Key-Value所组成,在逻辑上,这些Key-Value是无所谓排列顺序的。

在哈希链表中,这些Key-Value不再是彼此无关的存在,而是被一个链条串联起来,每一个key-Value都有它的前驱和后继Key-value,就像双向链表中的节点一样。这样一来,无序的哈希表拥有了固定的排列顺序。

使用业务场景:

  需要抽取系统中用户数据,给各个子业务系统使用,子系统对信息的查询频率很高,要注意查询性能。

  方案一:直接将用户信息放入redis缓存中。

  方案二:自己写哈希表。虽然在Java 中的LinkedHashMap已经对哈希链表做了很好的实现,但是为了加深印象,还是自己写简单实现。

  需要注意的是,以下代码并不是线程安全的,在并发情况下可以添加synchronized解决。

  1 package com.ai.channel.lrumap;
  2 
  3 import java.util.HashMap;
  4 import java.util.Iterator;
  5 import java.util.Set;
  6 
  7 /**
  8  * @Author zhangliwei
  9  * @Date 2018/11/5 下午4:02
 10  */
 11 
 12 public class LRUCache {
 13 
 14     private Node head;
 15     private Node end;
 16     private int limite;
 17     private HashMap<String, Node> hashMap ;
 18 
 19     public LRUCache(int limite) {
 20         this.limite = limite;
 21         hashMap = new HashMap<>();
 22     }
 23 
 24 
 25     public String get (String key){
 26         Node node = hashMap.get(key);
 27         if (null == node){
 28             return null;
 29         }
 30         refreshNode(node);
 31         return node.value;
 32     }
 33     public void put(String key, String value){
 34         Node node = hashMap.get(key);
 35         if (null == node){
 36             if (hashMap.size() >= limite){
 37                 String oldKey = removeNode(head);
 38                 hashMap.remove(oldKey);
 39             }
 40             node = new Node(key, value);
 41             addNode(node);
 42             hashMap.put(key, node);
 43         } else {
 44             node.value = value;
 45             refreshNode(node);
 46         }
 47     }
 48 
 49 //    public void remove(String key){
 50 //        Node node = hashMap.remove(key);
 51 //        removeNode(node);
 52 //        hashMap.remove(key);
 53 //    }
 54 
 55     private void refreshNode(Node node) {
 56         if (null == node){
 57             return;
 58         }
 59         removeNode(node);
 60         addNode(node);
 61     }
 62 
 63     private void addNode(Node node) {
 64         if (end != null){
 65             end.next = node;
 66             node.pre = end;
 67             node.next = null;
 68         }
 69         end = node;
 70         if (head == null){
 71             head = node;
 72         }
 73     }
 74 
 75     private String removeNode(Node node) {
 76         if (node == end){
 77             end = end.pre;
 78         } else if (node == head){
 79             head = head.next;
 80         } else {
 81             node.pre.next = node.next;
 82             node.next.pre = node.pre;
 83 
 84         }
 85 
 86         return node.key;
 87     }
 88 
 89     class Node{
 90         public Node(String key, String value) {
 91             this.key = key;
 92             this.value = value;
 93         }
 94 
 95         private Node pre;
 96 
 97         private Node next;
 98 
 99         private String key;
100 
101         private String value;
102 
103     }
104 
105     public static void main(String[] args) {
106         LRUCache lruCache = new LRUCache(5);
107         lruCache.put("1","user001");
108         lruCache.put("2","user002");
109         lruCache.put("3","user003");
110         lruCache.put("4","user004");
111         lruCache.put("5","user005");
112         lruCache.get("2");
113         lruCache.put("4","user004更新");
114         lruCache.put("6","user006");
115         System.out.println(lruCache.get("1"));
116         System.out.println(lruCache.get("6"));
117 
118         HashMap<String, Node> hashMap = lruCache.hashMap;
119         Set<String> strings = hashMap.keySet();
120         Iterator<String> iterator = strings.iterator();
121         while (iterator.hasNext()){
122             String next = iterator.next();
123             System.out.println(next + ": " + hashMap.get(next).value);
124         }
125 
126     }
127 }

 

posted @ 2018-11-05 17:59  小小虫飞飞  阅读(801)  评论(0编辑  收藏  举报