Frage

Ich weiß, es ist einfach zu implementieren, aber ich möchte etwas wieder zu verwenden, die bereits existieren.

Problem ich lösen will, ist, dass ich Konfiguration laden (von XML so möge ich sie in der Cache) für verschiedene Seiten, Rollen, ... so dass die Kombination der Eingänge kann sehr viel wachsen (aber in 99% nicht). Um damit umgehen zu 1%, ich mag einige max Anzahl der Elemente im Cache haben ...

Bis weiß, ich habe in Apache Commons gefunden org.apache.commons.collections.map.LRUMap und es sieht gut aus, will aber sonst auch etwas überprüfen. Alle Empfehlungen?

War es hilfreich?

Lösung

Sie können eine 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);

Andere Tipps

Dies ist eine alte Frage, aber für die Nachwelt wollte ich ConcurrentLinkedHashMap zur Liste, das ist fädeln sicher, im Gegensatz zu LRUMap . Die Benutzung ist ganz einfach:

ConcurrentMap<K, V> cache = new ConcurrentLinkedHashMap.Builder<K, V>()
    .maximumWeightedCapacity(1000)
    .build();

Und die Dokumentation hat einige gute Beispiele , wie wie das machen LRU-Cache-Größe Basis anstelle von Nummer-of-Artikel basiert.

Hier ist meine Implementierung, die ich eine optimale Anzahl von Elementen im Speicher läßt halten.

Der Punkt ist, dass ich zu Spur nicht halte von welchen Objekte derzeit verwendet werden, da ich eine Kombination aus einem LinkedHashMap für die MRU-Objekte und ein WeakHashMap für die LRU-Objekte verwenden. So ist die Cache-Kapazität ist nicht weniger als MRU Größe plus was auch immer der GC läßt mich halten. Jedes Mal, wenn Objekte aus der MRU fallen gehen sie zum LRU, solange die GC wird sie haben.

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);
}
}

Ich hatte auch gleiche Problem, und ich habe keine gute Bibliotheken gefunden ... also habe ich meine eigene erstellt.

simplelrucache bietet THREAD, sehr einfach, nicht ausgeschüttete LRU Caching mit TTL-Unterstützung. Es bietet zwei Implementierungen

  • Concurrent basierend auf ConcurrentLinkedHashMap
  • Synchronisiert basierend auf LinkedHashMap

Sie können finden sie hier .

Hier ist eine sehr einfache und leicht LRU-Cache in Java zu verwenden. Obwohl es kurz und einfach ist, ist es die Produktionsqualität. Der Code wird erklärt (Blick auf das README.md) und hat einige Unit-Tests.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top