我知道这很容易实现,但我想重用已经存在的东西。
我想解决的问题是,我会为不同的页面、角色等加载配置(从XML中),因此输入的组合可能会变得非常多(但在99%的情况下不会)。为了处理这1%,我想在缓存中设置一些最大数量的项目...
到目前为止,我已经找到了apache commons中的org.apache.commons.collections.map.LRUMap,并且看起来很好,但还想检查其他的东西。有什么推荐吗?
我知道这很容易实现,但我想重用已经存在的东西。
我想解决的问题是,我会为不同的页面、角色等加载配置(从XML中),因此输入的组合可能会变得非常多(但在99%的情况下不会)。为了处理这1%,我想在缓存中设置一些最大数量的项目...
到目前为止,我已经找到了apache commons中的org.apache.commons.collections.map.LRUMap,并且看起来很好,但还想检查其他的东西。有什么推荐吗?
// Create cache
final int MAX_ENTRIES = 100;
Map cache = new LinkedHashMap(MAX_ENTRIES+1, .75F, true) {
// This method is called just after a new entry has been added
public boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_ENTRIES;
}
};
// Add to cache
Object key = "key";
cache.put(key, object);
// Get object
Object o = cache.get(key);
if (o == null && !cache.containsKey(key)) {
// Object not in cache. If null is not a possible value in the cache,
// the call to cache.contains(key) is not needed
}
// If the cache is to be used by multiple threads,
// the cache must be wrapped with code to synchronize the methods
cache = (Map)Collections.synchronizedMap(cache);
这是一个老问题,但为了后人,我想列出ConcurrentLinkedHashMap,它是线程安全的,不像LRUMap。使用非常简单:
ConcurrentMap<K, V> cache = new ConcurrentLinkedHashMap.Builder<K, V>()
.maximumWeightedCapacity(1000)
.build();
文档中提供了一些很好的示例,例如如何使LRU缓存基于大小而不是项数。
这是我的实现方式,可以让我在内存中保留最佳数量的元素。
重点是我不需要跟踪当前正在使用的对象,因为我同时使用LinkedHashMap和WeakHashMap组合来处理MRU(最近最少使用)对象和LRU(最久未使用)对象。 因此,缓存容量不会小于MRU大小加上GC允许我保留的内容。每当对象从MRU中移除时,它们会在LRU中停留,只要GC允许。
public class Cache<K,V> {
final Map<K,V> MRUdata;
final Map<K,V> LRUdata;
public Cache(final int capacity)
{
LRUdata = new WeakHashMap<K, V>();
MRUdata = new LinkedHashMap<K, V>(capacity+1, 1.0f, true) {
protected boolean removeEldestEntry(Map.Entry<K,V> entry)
{
if (this.size() > capacity) {
LRUdata.put(entry.getKey(), entry.getValue());
return true;
}
return false;
};
};
}
public synchronized V tryGet(K key)
{
V value = MRUdata.get(key);
if (value!=null)
return value;
value = LRUdata.get(key);
if (value!=null) {
LRUdata.remove(key);
MRUdata.put(key, value);
}
return value;
}
public synchronized void set(K key, V value)
{
LRUdata.remove(key);
MRUdata.put(key, value);
}
}
我也曾遇到过同样的问题,但找不到好的库...所以我自己创建了一个。
simplelrucache提供线程安全、非常简单、非分布式LRU缓存与TTL支持。它提供了两种实现方式:
您可以在这里找到它。