我从网上获取了一些并发的LRU缓存实现,它们有HashMap和synchronized块。我想要的是使用ConcurrentHashMap并避免(在可行的情况下)使用synchronized块。我把ConcurrentHashMap而不是HashMap放了,一切都搞错了。线程在map.get(key)上退出。也许我的ConcurrentHashMap参数需要以某种方式定制?
private ConcurrentHashMap<Object, LRUListEntry> map;
protected class LRUListEntry extends Object
{
LRUListEntry next;
LRUListEntry prev;
Object value;
Object key;
int hits;
final int penalty = -1;
public String toString()
{
return key + "=" + value;
}
public Object getKey()
{
return key;
}
public Object getValue()
{
return value;
}
}
答案 0 :(得分:2)
问题是每次访问都会修改prev
和next
LRU引用,以便将条目重新排序为最近最少使用的条目。该实现假定这些操作是以原子方式执行的,如果同步块被删除则不是这样。 Java的LinkedHashMap
是一个很好的代码片段实现,在标准库中提供。
ConcurrentLinkedHashMap提供LRU算法的并发版本。 design document在高层次上描述了所使用的想法。该项目是Guava's Cache的基础,其中使用了presentation中描述的修改方法。如果您对低级细节感兴趣,这两个项目都有良好的代码级文档和单元测试。