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方法的原因