Auf der Suche nach einem einfachen Java-In-Memory-Cache [geschlossen]

102

Ich suche nach einem einfachen Java-In-Memory-Cache mit guter Parallelität (daher ist LinkedHashMap nicht gut genug), der regelmäßig auf die Festplatte serialisiert werden kann.

Eine Funktion, die ich brauche, die sich jedoch als schwer zu finden erwiesen hat, ist die Möglichkeit, ein Objekt zu "betrachten". Damit meine ich das Abrufen eines Objekts aus dem Cache, ohne dass der Cache das Objekt länger als sonst festhält.

Update: Eine zusätzliche Anforderung, die ich nicht erwähnt habe, ist, dass ich in der Lage sein muss, die zwischengespeicherten Objekte (sie enthalten Float-Arrays) direkt zu ändern.

Kann jemand irgendwelche Empfehlungen geben?

geistige Gesundheit
quelle
1
Ich suche etwas Ähnliches, das "im Prozess" und leichter ist. Ich möchte es verwenden, um einige Daten in einem Eclipse-Plugin im Heap zu speichern. Ehcache und JCS scheinen für meinen Geschmack zu schwer / verteilt / J2EE zu sein.
Uri
1
Mögliches Duplikat der Lightweight Java Object Cache API
Raedwald
Ich werde Apache Ignite ( ignite.apache.org )
Bhagat S.
1
Dass diese Frage geschlossen ist (6 Jahre später) und sich die Leute heute noch fragen, zeigt, wie das Moderatorsystem von SO versagt.
Dustinevan

Antworten:

61

Da diese Frage ursprünglich gestellt wurde, enthält die Guava-Bibliothek von Google jetzt einen leistungsstarken und flexiblen Cache. Ich würde empfehlen, dies zu verwenden.

geistige Gesundheit
quelle
3
Bitte beachten Sie, dass Spring den Guava-Cache nicht mehr unterstützt: stackoverflow.com/questions/44175085/…
Sünder
@sanity implementiert es Jcache?
Gaurav
Caffine ist auch eine nette und performante Caching-Bibliothek. Koffein ist eine leistungsstarke, nahezu optimale Caching-Bibliothek, die auf Java 8 basiert. Koffein bietet einen In-Memory-Cache mit einer von Google Guava inspirierten API
Slavus
37

Ehcache ist eine ziemlich gute Lösung dafür und bietet eine Möglichkeit, einen Blick darauf zu werfen ( getQuiet () ist die Methode), sodass der Leerlaufzeitstempel nicht aktualisiert wird. Intern wird Ehcache mit einer Reihe von Karten implementiert, ähnlich wie ConcurrentHashMap, sodass es ähnliche Vorteile für die Parallelität bietet.

Alex Miller
quelle
2
Vielen Dank, eine zusätzliche Frage: Wenn ich ein Objekt aus EHcache (z. B. einem Array) abrufe und ändere, wird das Objekt im Cache aktualisiert? dh. Behält EHCache Verweise auf die Objekte bei?
Vernunft
1
Ich glaube schon, aber um dies sicher zu tun, müssen Sie das Objekt natürlich angemessen sperren.
Alex Miller
Ich liebe ehcache, aber es ist ein 10-MB-Glas. Viel zu groß.
März 22/19
23

Wenn Sie etwas Einfaches brauchen, würde dies zur Rechnung passen?

Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());

Es wird nicht auf der Festplatte gespeichert, aber Sie sagten, Sie wollten einfach ...

Links:

(Wie Adam kommentierte, hat das Synchronisieren einer Karte einen Leistungseinbruch. Nicht zu sagen, dass die Idee keine Haare hat, aber als schnelle und schmutzige Lösung ausreichen würde.)

Evan
quelle
4
Das Synchronisieren einer ganzen gigantischen Karte ist eine schwere Strafe. Sie können schwache Typen problemlos in einer gleichzeitigen Hash-Map speichern und regelmäßig entfernen.
Adam Gent
7
ConcurrentHashMap ist besser als Collections.synchronizedMap stackoverflow.com/questions/6692008/…
Pablo Moretti
8
In Bezug auf die Leistung bietet ConcurrentHashMap eine absolut bessere Leistung, teilt jedoch nicht die Eigenschaften einer WeakHashMap, um dem Garbage Collector die Rückgewinnung von Speicher zu ermöglichen. Dies kann für Sie wichtig sein oder auch nicht.
Evan
4
Dann verwenden ConcurrentHashMap<WeakReference<T>>. docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal
19

Eine weitere Option für einen speicherinternen Java-Cache ist cache2k . Die In-Memory-Leistung ist EHCache und Google Guava überlegen (siehe Seite mit den Cache2k-Benchmarks) .

Das Verwendungsmuster ähnelt anderen Caches. Hier ist ein Beispiel:

Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
  .expireAfterWrite(5, TimeUnit.MINUTES)    // expire/refresh after 5 minutes
  .resilienceDuration(30, TimeUnit.SECONDS) // cope with at most 30 seconds
                                          // outage before propagating 
                                          // exceptions
  .refreshAhead(true)                       // keep fresh when expiring
  .loader(new CacheLoader<String, String>() {
    @Override
    public String load(final String key) throws Exception {
      return ....;
    }
  })
  .build();
String val = cache.peek("something");
cache.put("something", "hello");
val = cache.get("something");

Wenn Sie Google Guava als Abhängigkeit haben, ist das Ausprobieren des Guaven-Cache möglicherweise eine gute Alternative.

Cruftex
quelle
cruftex, wenn ich meine Anwendung schließe, zerstört der Cache alle registrierten Daten oder nein?
Menai Ala Eddine - Aladdin
10

Sie können einfach imcache verwenden . Ein Beispielcode ist unten.

void example(){
    Cache<Integer,Integer> cache = CacheBuilder.heapCache().
    cacheLoader(new CacheLoader<Integer, Integer>() {
        public Integer load(Integer key) {
            return null;
        }
    }).capacity(10000).build(); 
}
Yusufaytas
quelle
9

Versuche dies:

import java.util.*;

public class SimpleCacheManager {

    private static SimpleCacheManager instance;
    private static Object monitor = new Object();
    private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>());

    private SimpleCacheManager() {
    }

    public void put(String cacheKey, Object value) {
        cache.put(cacheKey, value);
    }

    public Object get(String cacheKey) {
        return cache.get(cacheKey);
    }

    public void clear(String cacheKey) {
        cache.put(cacheKey, null);
    }

    public void clear() {
        cache.clear();
    }

    public static SimpleCacheManager getInstance() {
        if (instance == null) {
            synchronized (monitor) {
                if (instance == null) {
                    instance = new SimpleCacheManager();
                }
            }
        }
        return instance;
    }

}
Serhii Bohutskyi
quelle
Die Probleme beim Verlassen auf eine synchronisierte Karte wurden bereits in anderen Antworten erörtert.
Vernunft
@sergeyB: Ich war auf der Suche nach einer ähnlichen Lösung , die einfach Cache für die Umsetzung ... Danke
Prakruti Pathik
1
public static SimpleCacheManager getInstance() {sollte public synchronized static SimpleCacheManager getInstance() {sonst if (instance == null) {nicht threadsicher sein. In diesem Fall können Sie das Monitorobjekt
Can Kavaklıoğlu
Darf ich empfehlen, eine Aufzählung für Singleton zu verwenden? dzone.com/articles/java-singletons-using-enum
Erk
3

Wie wäre es damit: https://commons.apache.org/proper/commons-jcs/ (auf neue Adresse aktualisiert, da JCS jetzt in Apache Commons ist)

TofuBeer
quelle
Es sieht so aus, als wollte @sanity einen leichten Cache.
Rodolfo
0

Versuchen Sie es mit Ehcache ? Sie können damit Ihre eigenen Caching-Ablaufalgorithmen einbinden, um Ihre Peek-Funktionalität zu steuern.

Sie können auf Festplatte, Datenbank, in einem Cluster usw. serialisieren.

Stephen
quelle