开发内存对象缓存

时间:2012-08-11 07:27:56

标签: java java-ee caching

我正在开发基于Web的医疗应用程序,需要创建一个小的内存中对象缓存。这是我的用例。

我们需要显示需要某些东西(血,肾等)的人提交的请求列表,并且它不会是一个巨大的列表,因为在给定的一天请求血液或其他任何东西将是有限的。请注意我们不想使用任何缓存API,因为它会是一种过度杀伤。我们的想法是创建一个Map并将其放在ApplicationContext中。

当任何人发出新请求时,我们将在应用程序上下文中更新该Map,并在请求到期时,我们将从Map中删除它们。我们还需要进一步研究以下几点。

  1. 需要设置最大元素限制。
  2. 如果达到最高限额,我们应该删除首先添加的条目。
  3. 处理任何同步问题。
  4. 请建议应该使用哪种数据结构以及在实施时应注意哪些事项。

4 个答案:

答案 0 :(得分:2)

谷歌的番石榴缓存怎么样?它实现起来非常简单并且非常易于使用:

Guava Cache

答案 1 :(得分:1)

对于OmniFaces项目,我们有类似的要求,我们选择了concurrentlinkedhashmap,其中有一个小的wrapper,用于跟踪缓存项目的有效期,并在每个项目时从缓存中清除它们请求。

另见:How would you implement an LRU cache in Java?

答案 2 :(得分:1)

如果您不想添加第三方库,您可以在LinkedHashMap之上自行实现。 LinkedHashMap非常适合用作缓存,您可以配置策略(删除最近最少使用或最旧的条目) 如果您相应地配置它,它将根据您的需要删除最旧的条目 对于线程安全,您始终可以使用Collections#synchronizedMap()

这是一个小example

答案 3 :(得分:0)

我相信LinkedHashMap正是您所需要的。您只需覆盖removeEldestEntry(...)方法,如果达到最大容量,它将自动删除旧条目。类似的东西:

import java.util.*;

class CacheMap<K,V> extends LinkedHashMap<K,V> {
    protected final int maxCapacity;
    public CacheMap(int maxCapacity) {
        this.maxCapacity = maxCapacity;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > maxCapacity;
    }
}

您可以实现更复杂的逻辑,例如删除非常旧的条目,即使最大值也是如此。没有达到容量。

如果同步原子地图操作就足够了,你可以将地图包装到Collections.synchronizedMap(...)

Map<K,V> map = Collections.synchronizedMap(new CacheMap<K,V>(capacity));

如果您需要更准确的同步,例如读取地图并在一个同步块中更新它,您需要自己使用synchronize (所有)代码块。