在java中使用多个使用者和单个生成器实现缓存

时间:2012-12-14 17:03:28

标签: java caching producer

我的要求是维护一个固定大小的缓存,它为基于Java的Web应用程序中的多个使用者和单个生成者提供支持。我的数据是这样的:

键1,键2,值

123,ABC,List1中

123,DEF,列表2

234,XYZ,项目list3

客户端或消费者将根据key1和key2查询此缓存。 因此,如果多个消费者试图同时访问相同的key1& 2,他们都应该从缓存中获取相同的数据作为响应。

我正在寻找最好的数据结构。 另请注意,缓存大小是固定的,因此如果生成器在尝试插入记录之前应该删除第一个元素,如果缓存已满。

我目前在地图中使用地图。即,键1用于外部映射,键2用于内部映射。但是我需要仔细查看它以获得我觉得效率低下的信息。

有什么建议吗?

4 个答案:

答案 0 :(得分:1)

首先,我会将您的缓存压缩为单个2分量密钥(即将key1和key2组合成复合密钥类)。

其次,我会使用现有的缓存实现,而不是重新发明轮子。对于“简单”用法,您可以同步对LinkedHashMap的访问(您可以使用removeEldestEntry()方法限制大小)。如果你需要更复杂的线程处理,那么我会看一些类似ehcacheGuava的内容(在其他答案中提到)。

答案 1 :(得分:0)

查看Google提供的有用实用程序库Guava,其中包含一些出色的缓存功能。特别是,它支持最大尺寸,并将自动处理驱逐。

对于2键问题,为什么不将Guava缓存(或任何实现)与另外一个包含2个键并从组合中生成单个键的类包装起来,例如:

public class MyCache<Key, Value> {
    private final Cache<CacheKey, Value> guavaCache = CacheBuilder.build()

    public void put(Key keyOne, Key keyTwo, Value value) {
        cache.put(new CacheKey(keyOne, keyTwo), value);
    }

    public Value get(Key keyOne, Key keyTwo) {
        return cache.getIfPresent(new CacheKey(keyOne, keyTwo));
    }

    private static final class CacheKey {
        private final Key keyOne;
        private final Key keyTwo;

        CacheKey(Key keyOne, Key keyTwo) {
             this.keyOne = keyOne;
             this.keyTwo = keyTwo;
        }

        @Override
        public int hashCode() {
            int hash = keyOne == null ? 0 : keyOne.hashCode();
            return hash + 31 * keyTwo == null ? 0 : keyTwo.hashCode();
        }

        @Override
        public boolean equals(Object o) {
            // implementation omitted
        }
    }
}

答案 2 :(得分:0)

我建议使用加载因子1备份所需大小Map的自定义ConcurrentHashMap实施,并在里面设置一个计数器,以确保包裹的ConcurrentHashMap不包含超出您想要的数量它包含。

答案 3 :(得分:0)

您可以为两个密钥维护两个ConcurrentHashMaps,如果没有冲突的可能,则保留一个。要记住最旧的密钥,您可以使用要在达到缓存大小限制时删除的两个最旧的密钥来维护队列。