【Java】MySQL jdbc连接器中的LRU是如何实现的

1. JDBC中的LRUCache:

package com.mysql.cj.util;

import java.util.LinkedHashMap;
import java.util.Map.Entry;

public class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private static final long serialVersionUID = 1L;
    protected int maxElements;

    public LRUCache(int maxSize) {
        super(maxSize, 0.75F, true);
        this.maxElements = maxSize;
    }

    protected boolean removeEldestEntry(Entry<K, V> eldest) {
        return this.size() > this.maxElements;
    }
}

可以看到其实现的LRUCache其实是继承自JDK中LinkedHashMap类的,并重写了removeEldestEntry方法,该方法返回一个布尔值,即当前集合大小大于规定的大小时返回true,否则返回false。

2.LinkedHashMap中的removeEldestEntry()方法

以下是LinkedHashMap中removeEldestEntry的方法,默认返回是false。

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return false;
}

接着点击removeEldestEntry方法查找谁调用了它,结果跳到了如下代码:

void afterNodeInsertion(boolean evict) { // possibly remove eldest
   LinkedHashMap.Entry<K,V> first;
    if (evict && (first = head) != null && removeEldestEntry(first)) {
        K key = first.key;
        removeNode(hash(key), key, null, false, true);
    }
}

顾名思义,在添加进新元素后,会执行该方法判断执行要不要踢出最久未被使用的元素。其中evict踢出状态,时putVal传给该函数的,除了读取元素时为false,其它情况都为true;当且仅当踢出状态为真、链表不为空时以及需要移除最久未使用的元素时,才会移除元素。

3. LinkedHashMap是如何读取元素的

需要知道的一点是,LinkedHashMap在读取元素时,会将元素移动到链表尾部,这样就模拟了类似用栈实现LRU的方法,也解释了为什么读取元素是也会调用putVal方法的原因

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章