-1

我从网上获取了一些并发 LRU 缓存实现,它们有 HashMap 和同步块。我想要的是使用 ConcurrentHashMap 并避免(在可能的情况下)使用同步块。我放了 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;
            }
        }
4

1 回答 1

2

问题是每次访问时都会修改prev和LRU 引用,以将条目重新排序为最近最少使用的条目。next该实现假定这些操作是原子执行的,如果同步块被删除,则不是这样。JavaLinkedHashMap是您的代码片段的一个很好的实现,并在标准库中提供。

ConcurrentLinkedHashMap提供了 LRU 算法的并发版本。设计文档从高层次上描述了所使用的想法。该项目是Guava 的 Cache的基础,采用本演示文稿中描述的修改方法。如果您对底层细节感兴趣,这两个项目都有很好的代码级文档和单元测试。

于 2012-12-23T20:22:53.773 回答