原文:https://blog.csdn.net/ranzai1986/article/details/86727016
LUR思想 数据使用的时间越近,越不会被淘汰。当缓存空间不足,删除使用时间最远的那条数据。 实现思想: 通过两个hashMap Map<String, Object> dataMap :存储数据 Map<String, Node> nodeMap :使用链表储存位置 当插入数据,将插入的数据位置置于首位, 如果超出缓存大小,删除last 当query, 将当前查询的数据剪切到首位 源码部分: /** * 算法接口 */ public interface LURArithmetic { public void add(String key, Object data); public Object get(String key); } /** * 算法实现 */ public class LURArithmeticImpl implements LURArithmetic { private LURCache dataCache; public LURArithmeticImpl(int size) { dataCache = new LURCacheImpl(size); } @Override public void add(String key, Object data) { dataCache.insert(key, data); } @Override public Object get(String key) { return dataCache.update(key); } } /** * 缓冲接口 */ public interface LURCache { public void insert(String key, Object data); public Object update(String key); } /** * 缓冲实现 */ public class LURCacheImpl implements LURCache { private static final String HEAD_KEY = "head"; private static final String TAIL_KEY = "tail"; private Map<String, Object> dataMap = new HashMap<>(); private Map<String, Node> nodeMap = new HashMap<>(); private Node head = new Node(HEAD_KEY); //pointer to first node private Node tail = new Node(TAIL_KEY); //pointer to last node private Object lock = new Object(); private int MAX_SIZE; public LURCacheImpl(int size) { head.setNext(tail); tail.setPre(head); this.MAX_SIZE = size; } @Override public void insert(String key, Object data) { synchronized(lock) { if (dataMap.get(key) != null) { return; } dataMap.put(key, data); Node newNode = new Node(key); nodeMap.put(key, newNode); addFirst(newNode);//添加到first monitorCache();//检查是否超出范围,如果超出,则删除last } } @Override public Object update(String key) { synchronized(lock) { Object data = dataMap.get(key); if (data != null) { //移动当前对象到首位 moveToFirst(nodeMap.get(key)); } return data; } } private void monitorCache() { if (nodeMap.size() > MAX_SIZE) { removeLast(); } } private void removeLast() { if (! isEmpty()) { Node last = tail.getPre(); last.getPre().setNext(tail); tail.setPre(last.getPre()); } } private void moveToFirst(Node node) { cut(node); addFirst(node); } private void cut(Node node) { node.getPre().setNext(node.getNext()); node.getNext().setPre(node.getPre()); } private void addFirst(Node node) { Node first = head.getNext(); first.setPre(node); node.setNext(first); node.setPre(head); head.setNext(node); } private boolean isEmpty() { return tail.getPre().getKey().equals(HEAD_KEY); } public void print() { System.out.println("************************** start **************************"); Node node = head; while(node.hasNext() && !node.getNext().getKey().equals(TAIL_KEY)) { Node next = node.getNext(); String key = next.getKey(); node = next; System.out.println("key = " + key + ", value = " + dataMap.get(key)); } System.out.println("************************** end **************************"); } } /** * 节点bean */ public class Node { private String key; private Node pre; private Node next; public Node(String key) { this.key = key; } public Node getPre() { return pre; } public void setPre(Node pre) { this.pre = pre; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } public String getKey() { return key; } public boolean hasNext() { return next != null; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2019-03-22 springboot retry
2018-03-22 jpa-入门级测试
2018-03-22 jpa-入门.缓存配置ehcache.xml
2018-03-22 jpa-入门测试
2018-03-22 JPA