当前位置:  开发笔记 > 编程语言 > 正文

在java中使用简单易用的LRU缓存

如何解决《在java中使用简单易用的LRU缓存》经验,为你挑选了3个好方法。

我知道实现起来很简单,但我想重用已经存在的东西.

我想解决的问题是我为不同的页面,角色加载配置(来自XML,所以我想缓存它们)......所以输入的组合可以增长很多(但99%不会).要处理这个1%,我希望在缓存中有一些最大数量的项目...

直到知道我在apache commons中找到了org.apache.commons.collections.map.LRUMap它看起来很好但是想要检查别的东西.有什么建议?



1> Guido..:

您可以使用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);


我今天发现了LinkedHashMap的那个方面,它的惊人之处是多么简单.经验教训:了解您的API.
来自公共收藏的LRUMap也是一个不错的选择.

2> Bobby Powers..:

这是一个老问题,但对于后人我想列出ConcurrentLinkedHashMap,这是线程安全的,不像LRUMap.用法很简单:

ConcurrentMap cache = new ConcurrentLinkedHashMap.Builder()
    .maximumWeightedCapacity(1000)
    .build();

文档中有一些很好的例子,比如如何使LRU缓存大小而不是基于项目数.


[Caffeine](https://github.com/ben-manes/caffeine)是Java 8重写,[更快](https://github.com/ben-manes/caffeine/wiki/Benchmarks)并提供更多[功能](https://github.com/ben-manes/caffeine/wiki/Cache).

3> 小智..:

这是我的实现,它允许我在内存中保持最佳数量的元素.

关键是我不需要跟踪当前正在使用的对象,因为我使用了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);
}
}

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有