我正在寻找具有以下行为的内存缓存。
我知道如何实现这样的缓存,但是有人知道现有的库,它提供了这样的缓存。
这是我对界面的看法。缓存有一些元素
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。使用此解决方案,我可以使用现有的缓存,例如Ehcache或Guava Caches。
但在我开始编写自己的库之前,我正在寻找现有的代码。
答案 0 :(得分:2)
您是否寻找某种分布式缓存并希望在多个实例上传播初始负载,对吧?
Hazlecast持久数据存储API总是值得一看。
启动初始化从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.
}
请注意我不会将此称为“缓存”。
您要求的策略是定时器触发的重新初始化。缓存通常意味着
答案 3 :(得分:0)
听起来你需要覆盖HashMap.get()并添加一个if,它有一个用于重置的计时器,以及在必要时加载的代码。
如果你不需要更多,我就不会为它寻找一个库。无论如何,大多数缓存在首次访问时都不会完全填充。
答案 4 :(得分:0)
我也看不出这是一个图书馆。仅仅因为您的要求非常特殊:
我会删除懒惰的“需求”并简单地使用ExecutorService.newSingleThreadScheduledExecutor(ThreadFactory)
和一个预定的守护程序线程,该程序每小时重新加载一个ConcurrentHashMap,从应用程序启动开始(异步)。这很简单。
如果你想让它更复杂,请使用get方法synchronized
并检查isInitialized
或使用双重检查锁定,或者,或者。你看到这到底在哪里?你创建的这个小要求让你想去图书馆,但是由于其他要求,我只是质疑它根本没有任何意义并且寻求更简单的解决方案。