我知道实现起来很简单,但我想重用已经存在的东西.
我想解决的问题是我为不同的页面,角色加载配置(来自XML,所以我想缓存它们)......所以输入的组合可以增长很多(但99%不会).要处理这个1%,我希望在缓存中有一些最大数量的项目...
直到知道我在apache commons中找到了org.apache.commons.collections.map.LRUMap它看起来很好但是想要检查别的东西.有什么建议?
您可以使用LinkedHashMap(Java 1.4+):
// 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.用法很简单:
ConcurrentMapcache = new ConcurrentLinkedHashMap.Builder () .maximumWeightedCapacity(1000) .build();
文档中有一些很好的例子,比如如何使LRU缓存大小而不是基于项目数.
这是我的实现,它允许我在内存中保持最佳数量的元素.
关键是我不需要跟踪当前正在使用的对象,因为我使用了MRU对象的LinkedHashMap和LRU对象的WeakHashMap的组合.所以缓存容量不小于MRU大小加上GC允许我保留的内容.每当物体从MRU上掉落时,只要GC具有它们,它们就会进入LRU.
public class Cache{ final Map MRUdata; final Map LRUdata; public Cache(final int capacity) { LRUdata = new WeakHashMap (); MRUdata = new LinkedHashMap (capacity+1, 1.0f, true) { protected boolean removeEldestEntry(Map.Entry 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); } }