寻找一次性内存缓存

时间:2012-02-25 10:43:14

标签: java caching

我正在寻找具有以下行为的内存缓存。

  • 在第一次访问时或初始化后,它会读取所有要一次缓存的数据。例如。表的所​​有行。
  • 一小时后,清除完整缓存并立即再次读取所有数据。
  • 可以按需清除缓存。

我知道如何实现这样的缓存,但是有人知道现有的库,它提供了这样的缓存。

这是我对界面的看法。缓存有一些元素

Element element = new Element(Object key, Object objectToCache);

加载器提供所有元素

Collection<Element> elements = myLoader.getElements();

最后有缓存

public Cache {
  public Cache(CacheLoader loader, int timeToReload) {
    ...
  }

  public Object getValueForKey(Object key {
    ...
  }

  ...
}

解决方案是使用具有单个条目的缓存,该条目是实际条目的HashMap。使用此解决方案,我可以使用现有的缓存,例如EhcacheGuava Caches

但在我开始编写自己的库之前,我正在寻找现有的代码。

5 个答案:

答案 0 :(得分:2)

您是否寻找某种分布式缓存并希望在多个实例上传播初始负载,对吧?

Hazlecast持久数据存储API总是值得一看。

Hazlecast Doc

  

启动初始化从1.9.3开始,MapLoader拥有新的MapLoader.loadAllKeys API。它用于在首次触摸/使用地图时预先填充内存中的地图。如果MapLoader.loadAllKeys返回NULL,则不会加载任何内容。您的MapLoader.loadAllKeys实现可以返回全部或部分键。例如,您可以选择并仅返回热键。另请注意,这是预填充地图的最快方式,因为Hazelcast将通过让每个节点加载条目的所有部分来优化加载过程。

结合hazelcast.initial.min.cluster.size配置属性,您可以分发初始负载。

答案 1 :(得分:1)

我不确定您需要什么类型的收藏(地图,设置,列表或队列),但请查看Google Guava Cache implemetantions

答案 2 :(得分:0)

这个功能可能很容易有效地包装在库中。 毕竟,它归结为每小时都有一个线程调用reinitalize函数。

吸气剂:

if (collection == null) reinitialize();
return collection.get(key);

清算线程:

while(true) {
  Thread.sleep(60*60);
  collection = null; // probably as a method.
}

请注意我不会将此称为“缓存”

您要求的策略是定时器触发的重新初始化。缓存通常意味着

  • 仅延迟加载所需记录
  • 单个记录的LRU或基于年龄的到期

答案 3 :(得分:0)

听起来你需要覆盖HashMap.get()并添加一个if,它有一个用于重置的计时器,以及在必要时加载的代码。

如果你不需要更多,我就不会为它寻找一个库。无论如何,大多数缓存在首次访问时都不会完全填充。

答案 4 :(得分:0)

我也看不出这是一个图书馆。仅仅因为您的要求非常特殊:

  • 您有一个很小的数据集可以缓存或大量内存,您可以一次加载所有内容
  • 但你想懒洋洋地初始化'Cache'(我宁愿称之为内存数据结构),可能是因为你不想放慢app启动速度
  • 你可以让缓存永远填满

我会删除懒惰的“需求”并简单地使用ExecutorService.newSingleThreadScheduledExecutor(ThreadFactory)和一个预定的守护程序线程,该程序每小时重新加载一个ConcurrentHashMap,从应用程序启动开始(异步)。这很简单。

如果你想让它更复杂,请使用get方法synchronized并检查isInitialized或使用双重检查锁定,或者,或者。你看到这到底在哪里?你创建的这个小要求让你想去图书馆,但是由于其他要求,我只是质疑它根本没有任何意义并且寻求更简单的解决方案。