服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 浅谈java如何实现Redis的LRU缓存机制

浅谈java如何实现Redis的LRU缓存机制

2021-09-18 11:33醉酒的小男人 Java教程

今天给大家带来的是关于Java的相关知识,文章围绕着java如何实现Redis的LRU缓存机制展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下

LRU概述

最近使用的放在前面,最近没用的放在后面,如果来了一个新的数,此时内存满了,就需要把旧的数淘汰,那为了方便移动数据,肯定就得使用链表类似的数据结构,再加上要判断这条数据是不是最新的或者最旧的那么应该也要使用hashmap等key-value形式的数据结构。

使用LinkedHashMap实现

  1. package thread;
  2. import java.util.LinkedHashMap;
  3. import java.util.Map;
  4.  
  5. public class LRUCacheTest {
  6. int capacity;
  7. Map<Integer,Integer> map;
  8.  
  9. public LRUCacheTest(int capacity){
  10. this.capacity = capacity;
  11. map = new LinkedHashMap<>();
  12. }
  13.  
  14. public int get(int key){
  15. //没有找到
  16. if(!map.containsKey(key)){
  17. return -1;
  18. }
  19. Integer value = map.remove(key);
  20. map.put(key,value);
  21. return value;
  22. }
  23.  
  24. public void put(int key,int value){
  25. if(map.containsKey(key)){
  26. map.remove(key);
  27. map.put(key,value);
  28. return;
  29. }
  30. map.put(key,value);
  31. //超出capacity,删除最久没用的即第一个,或者可以复写removeEldestEntry方法
  32. if(map.size() > capacity){
  33. map.remove(map.entrySet().iterator().next().getKey());
  34. }
  35.  
  36. }
  37.  
  38. public static void main(String[] args) {
  39. LRUCacheTest lruCache = new LRUCacheTest(10);
  40. for (int i = 0; i < 10; i++) {
  41. lruCache.map.put(i,i);
  42. System.out.print(lruCache.map.size()+"\t");
  43. }
  44. System.out.println();
  45. System.out.println(lruCache.map);
  46. lruCache.put(10,200);
  47. System.out.println(lruCache.map);
  48. lruCache.put(11,100);
  49. System.out.println(lruCache.map);
  50. lruCache.get(2);
  51. System.out.println(lruCache.map);
  52. }
  53.  
  54. }

浅谈java如何实现Redis的LRU缓存机制

结果来看是正确的,距离当前时间最远的数据被淘汰

使用LinkedHashMap简单方法实现

LinkedHashMap是维护了双向链表的HashMap,保持了插入元素的顺序。

LinkedHashMap提供了一个钩子方法,在新插入元素后可以决定是否删除最老的元素。

复写removeEldestEntry实现

  1. package thread;
  2. import java.util.LinkedHashMap;
  3. import java.util.Map;
  4.  
  5. public class LRUByLinkedHashMap extends LinkedHashMap<Integer,Integer> {
  6. /**
  7. * LRU中最大元素数量
  8. */
  9. private int maxSize;
  10.  
  11. public LRUByLinkedHashMap(int maxSize) {
  12. // 容量为最大值/0.75,即最大负载容量为maxSize
  13. // accessOrder=true 根据查询排序,即最近被使用的放到后面
  14. super((int) Math.ceil(maxSize / 0.75) + 1, 0.75f, true);
  15. this.maxSize = maxSize;
  16. }
  17.  
  18. /**
  19. * 此方法为钩子方法,map插入元素时会调用此方法
  20. * 此方法返回true则证明删除最老的因子
  21. * @param eldest
  22. * @return
  23. */
  24. @Override
  25. protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
  26. return size() > maxSize;
  27. }
  28.  
  29. public static void main(String[] args) {
  30. LRUByLinkedHashMap hashMap = new LRUByLinkedHashMap(10);
  31. for (int i = 0; i < 10; i++) {
  32. hashMap.put(i,i);
  33. System.out.print(hashMap.size()+"\t");
  34. }
  35. System.out.println();
  36. System.out.println(hashMap);
  37. hashMap.put(10,200);
  38. System.out.println(hashMap);
  39. hashMap.put(11,100);
  40. System.out.println(hashMap);
  41. hashMap.get(10);
  42. System.out.println(hashMap);
  43. }
  44.  
  45. }

浅谈java如何实现Redis的LRU缓存机制

双链表+hashmap

  1. package thread;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4.  
  5. public class LRURedis {
  6. private int capacity;
  7. private Map<Integer,ListNode> map;
  8. private ListNode head;
  9. private ListNode tail;
  10.  
  11. public LRURedis(int capacity){
  12. this.capacity = capacity;
  13. map = new HashMap<>();
  14. head = new ListNode(-1,-1);
  15. tail = new ListNode(-1,-1);
  16. head.next = tail;
  17. tail.pre = head;
  18. }
  19.  
  20. public int get(int key){
  21. if(!map.containsKey(key)){
  22. return -1;
  23. }
  24. ListNode node = map.get(key);
  25. node.pre.next = node.next;
  26. node.next.pre = node.pre;
  27. return node.val;
  28. }
  29.  
  30. public void put(int key,int value){
  31. if (get(key)!=-1){
  32. map.get(key).val = value;
  33. return;
  34. }
  35.  
  36. ListNode node = new ListNode(key,value);
  37. map.put(key,node);
  38. moveToTail(node);
  39.  
  40. if (map.size() > capacity){
  41. map.remove(head.next.key);
  42. head.next = head.next.next;
  43. head.next.pre = head;
  44. }
  45.  
  46. }
  47.  
  48. //把节点移动到尾巴
  49. private void moveToTail(ListNode node) {
  50. node.pre = tail.pre;
  51. tail.pre = node;
  52. node.pre.next = node;
  53. node.next = tail;
  54. }
  55.  
  56. //定义双向链表节点
  57. private class ListNode{
  58. int key;
  59. int val;
  60. ListNode pre;
  61. ListNode next;
  62.  
  63. //初始化双向链表
  64. public ListNode(int key,int val){
  65. this.key = key;
  66. this.val = val;
  67. pre = null;
  68. next = null;
  69. }
  70. }
  71. }

到此这篇关于浅谈java如何实现Redis的LRU缓存机制的文章就介绍到这了,更多相关java实现Redis的LRU缓存机制内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/xiaowanzi_zj/article/details/117906792

延伸 · 阅读

精彩推荐
  • Java教程Java8中Stream使用的一个注意事项

    Java8中Stream使用的一个注意事项

    最近在工作中发现了对于集合操作转换的神器,java8新特性 stream,但在使用中遇到了一个非常重要的注意点,所以这篇文章主要给大家介绍了关于Java8中S...

    阿杜7472021-02-04
  • Java教程Java实现抢红包功能

    Java实现抢红包功能

    这篇文章主要为大家详细介绍了Java实现抢红包功能,采用多线程模拟多人同时抢红包,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    这篇文章主要介绍了Java使用SAX解析xml的示例,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程小米推送Java代码

    小米推送Java代码

    今天小编就为大家分享一篇关于小米推送Java代码,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...

    富贵稳中求8032021-07-12
  • Java教程20个非常实用的Java程序代码片段

    20个非常实用的Java程序代码片段

    这篇文章主要为大家分享了20个非常实用的Java程序片段,对java开发项目有所帮助,感兴趣的小伙伴们可以参考一下 ...

    lijiao5352020-04-06
  • Java教程xml与Java对象的转换详解

    xml与Java对象的转换详解

    这篇文章主要介绍了xml与Java对象的转换详解的相关资料,需要的朋友可以参考下...

    Java教程网2942020-09-17
  • Java教程Java BufferWriter写文件写不进去或缺失数据的解决

    Java BufferWriter写文件写不进去或缺失数据的解决

    这篇文章主要介绍了Java BufferWriter写文件写不进去或缺失数据的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望...

    spcoder14552021-10-18
  • Java教程升级IDEA后Lombok不能使用的解决方法

    升级IDEA后Lombok不能使用的解决方法

    最近看到提示IDEA提示升级,寻思已经有好久没有升过级了。升级完毕重启之后,突然发现好多错误,本文就来介绍一下如何解决,感兴趣的可以了解一下...

    程序猿DD9332021-10-08