1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        手動(dòng)實(shí)現(xiàn)Redis的LRU緩存機(jī)制

        共 7929字,需瀏覽 16分鐘

         ·

        2021-03-27 10:34

        點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

        優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

        76套java從入門(mén)到精通實(shí)戰(zhàn)課程分享

        前言

        最近在逛博客的時(shí)候看到了有關(guān)Redis方面的面試題,其中提到了Redis在內(nèi)存達(dá)到最大限制的時(shí)候會(huì)使用LRU等淘汰機(jī)制,然后找了這方面的一些資料與大家分享一下。LRU總體大概是這樣的,最近使用的放在前面,最近沒(méi)用的放在后面,如果來(lái)了一個(gè)新的數(shù),此時(shí)內(nèi)存滿了,就需要把舊的數(shù)淘汰,那為了方便移動(dòng)數(shù)據(jù),肯定就得使用鏈表類似的數(shù)據(jù)結(jié)構(gòu),再加上要判斷這條數(shù)據(jù)是不是最新的或者最舊的那么應(yīng)該也要使用hashmap等key-value形式的數(shù)據(jù)結(jié)構(gòu)。

        第一種實(shí)現(xiàn)(使用LinkedHashMap)

        public class LRUCache {

            int capacity;
            Map<Integer,Integer> map;

            public LRUCache(int capacity){
                this.capacity = capacity;
                map = new LinkedHashMap<>();
            }

            public int get(int key){
                //如果沒(méi)有找到
                if (!map.containsKey(key)){
                    return -1;
                }
                //找到了就刷新數(shù)據(jù)
                Integer value = map.remove(key);
                map.put(key,value);
                return value;
            }

            public void put(int key,int value){
                if (map.containsKey(key)){
                    map.remove(key);
                    map.put(key,value);
                    return;
                }
                map.put(key,value);
                //超出capacity,刪除最久沒(méi)用的即第一個(gè),或者可以復(fù)寫(xiě)removeEldestEntry方法
                if (map.size() > capacity){
                    map.remove(map.entrySet().iterator().next().getKey());
                }
            }

            public static void main(String[] args) {
                LRUCache lruCache = new LRUCache(10);
                for (int i = 0; i < 10; i++) {
                    lruCache.map.put(i,i);
                    System.out.println(lruCache.map.size());
                }
                System.out.println(lruCache.map);
                lruCache.put(10,200);
                System.out.println(lruCache.map);
            }

        第二種實(shí)現(xiàn)(雙鏈表+hashmap)

        public class LRUCache {

            private int capacity;
            private Map<Integer,ListNode>map;
            private ListNode head;
            private ListNode tail;

            public LRUCache2(int capacity){
                this.capacity = capacity;
                map = new HashMap<>();
                head = new ListNode(-1,-1);
                tail = new ListNode(-1,-1);
                head.next = tail;
                tail.pre = head;
            }

            public int get(int key){
                if (!map.containsKey(key)){
                    return -1;
                }
                ListNode node = map.get(key);
                node.pre.next = node.next;
                node.next.pre = node.pre;
                return node.val;
            }

            public void put(int key,int value){
                if (get(key)!=-1){
                    map.get(key).val = value;
                    return;
                }
                ListNode node = new ListNode(key,value);
                map.put(key,node);
                moveToTail(node);

                if (map.size() > capacity){
                    map.remove(head.next.key);
                    head.next = head.next.next;
                    head.next.pre = head;
                }
            }

            //把節(jié)點(diǎn)移動(dòng)到尾巴
            private void moveToTail(ListNode node) {
                node.pre = tail.pre;
                tail.pre = node;
                node.pre.next = node;
                node.next = tail;
            }

            //定義雙向鏈表節(jié)點(diǎn)
            private class ListNode{
                int key;
                int val;
                ListNode pre;
                ListNode next;

                //初始化雙向鏈表
                public ListNode(int key,int val){
                    this.key = key;
                    this.val = val;
                    pre = null;
                    next = null;
                }
            }
        }

        像第一種方式,如果復(fù)寫(xiě)removeEldestEntry會(huì)更簡(jiǎn)單,這里簡(jiǎn)單的展示一下

        public class LRUCache extends LinkedHashMap<Integer,Integer> {


            private int capacity;
            
            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
                return size() > capacity;
            }
        }


        ————————————————

        版權(quán)聲明:本文為CSDN博主「拉霍拉卡」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

        原文鏈接:

        https://blog.csdn.net/Grady00/article/details/115168822





        粉絲福利:Java從入門(mén)到入土學(xué)習(xí)路線圖

        ??????

        ??長(zhǎng)按上方微信二維碼 2 秒


        感謝點(diǎn)贊支持下哈 

        瀏覽 66
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国语对白真实对话淫语 | 大乳奶水videos巨大乱叫 | 男女叉叉叉视频 | 91高清黄色视频 | 男生的小鸡鸡插入女生的小鸡鸡 | 夜夜嗨aⅴ免费视频 | 女人被爽到呻吟的床戏不忠 | 打炮网址| 下载操逼 | 大肉大捧一进一出两腿 |