背景资料
您可以使用LinkedHashMap制作LRU缓存,如at this link所示。基本上,你只是:
我的问题
这是一个非常标准的LRU缓存实现。但有一件事我无法弄清楚如何在LinkedHashMap删除条目时通知它,因为它最近没有使用它。
我知道我可以让removeEldestEntry提供某种形式的通知......但是当有新的插入(放入)底层地图时,有没有办法检索从缓存中删除的元素?或者,有没有办法查询从缓存中删除的最后一项?
答案 0 :(得分:2)
您可以通过线程本地存储的一些创造性使用来实现它:
class LRUCacheLHM<K,V> extends LinkedHashMap<K,V> {
private int capacity;
public LRUCacheLHM(int capacity) {
//1 extra element as add happens before remove (101), and load factor big
//enough to avoid triggering resize. True = keep in access order.
super(capacity + 1, 1.1f, true);
this.capacity = capacity;
}
private ThreadLocal<Map.Entry<K,V>> removed = new ThreadLocal<Map.Entry<K,V>>();
private ThreadLocal<Boolean> report = new ThreadLocal<Boolean>();
{
report.set(false);
}
@Override
public boolean removeEldestEntry(Map.Entry<K,V> eldest) {
boolean res = size() > capacity;
if (res && report.get()) {
removed.set(eldest);
}
return res;
}
public Map.Entry<K,V> place(K k, V v) {
report.set(true);
put(k, v);
try {
return removed.get();
} finally {
removed.set(null);
report.set(false);
}
}
}
place(K,V)
方法背后的想法是向removeEldestEntry
发出信号,表示我们希望通过将线程本地report
标志设置为true
来获取最长条目。当removeEldestEntry
看到此标志并知道正在删除某个条目时,它会将最旧的条目放在report
变量中,该变量也是线程本地的。
removeEldestEntry
对put
方法的调用发生了对null
的调用。之后,最长的条目是report
,或者位于准备收获的set(null)
变量内。
在removed
上调用Dictionary<string[], Dictionary<string, float>> data
对于避免延迟内存泄漏非常重要。