标签:imp ast put 抽取 线程 head ring else 一个
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 }
标签:imp ast put 抽取 线程 head ring else 一个
原文地址:https://www.cnblogs.com/zhangliwei/p/9910561.html