1. Einführung
Schauen wir uns in diesem Artikel Koffein an - eine Hochleistungs -Java -Cache -Bibliothek.
Ein grundlegender Unterschied zwischen Cache und Karte besteht darin, dass Caches gespeicherte Elemente recyceln kann.
Die Recycling -Richtlinie besteht darin, Objekte zu einer bestimmten Zeit zu löschen. Diese Strategie wirkt sich direkt auf die Cache -Hit -Rate aus - eine wichtige Funktion der Cache -Bibliothek.
Koffein bietet aufgrund der Verwendung der Fenster-Tinylfu-Recyclingstrategie eine nahezu optimale Trefferquote.
2. Abhängigkeit
Wir müssen die Koffeinabhängigkeit in pom.xml hinzufügen:
<Depopentcy> <gruppe> com.github.ben-Manes.Caffein </Groupid> <artifactId> Coffein </artifactid> <version> 2.5.5 </Version> </abhängig>
Die neueste Version von Koffein finden Sie in Maven Central.
3. Füllen Sie den Cache aus
Werfen wir einen Blick auf die drei Cache -Füllstrategien von Coffein: Handbuch, synchrone Belastung und asynchrones Laden.
Zunächst schreiben wir eine Klasse, damit der Werttyp im Cache gespeichert wird:
Class DataObject {private endgültige Zeichenfolgedaten; private statische Int -Objektcounter = 0; // Standardkonstruktoren/Getters öffentliche statische DataObject get (String -Daten) {ObjectCounter ++; Neue DataObject (Daten) zurückgeben; }}3.1. Manuelle Füllung
In dieser Strategie setzen wir den Wert manuell in den Cache ein, bevor wir ihn abrufen.
Lassen Sie uns den Cache initialisieren:
Cache <string, dataObject> cache = coffein.newbuilder () .expreaAnrite (1, timeUnit.minuts) .maximumsize (100) .build ();
Jetzt können wir die Getifpresent -Methode verwenden, um einige Werte aus dem Cache zu erhalten. Wenn dieser Wert im Cache nicht vorhanden ist, gibt diese Methode NULL zurück:
String key = "a"; DataObject dataObject = cache.getIfPresent (Schlüssel); Assertnull (DataObject);
Wir können die Put -Methode verwenden, um den Cache manuell zu füllen:
cache.put (Schlüssel, DataObject); dataObject = cache.getIfPresent (Schlüssel); Assertnotnull (DataObject);
Wir können auch die GET -Methode verwenden, um den Wert zu erhalten, der eine Funktion mit der Parameterschlüssel als Parameter übergibt. Wenn der Schlüssel im Cache nicht vorhanden ist, wird die Funktion verwendet, um einen Fallback -Wert bereitzustellen, der nach der Berechnung in den Cache eingefügt wird:
DataObject = cache .get (Schlüssel, k -> dataObject.get ("Daten für a")); Assertnotnull (DataObject); assertequals ("Daten für eine", dataObject.getData ());Die GET -Methode kann Berechnungen atomisch durchführen. Dies bedeutet, dass Sie die Berechnung nur einmal durchführen - auch wenn mehrere Threads gleichzeitig den Wert anfordern. Deshalb ist die Verwendung von GET besser als Getifpresent.
Manchmal müssen wir einige zwischengespeicherte Werte manuell ungültig machen:
Cache.invalidat (Schlüssel); dataObject = cache.getIfPresent (Schlüssel); Assertnull (DataObject);
3.2. Synchronbelastung
Diese Methode zum Laden von Cache verwendet eine GET -Methode mit einer manuellen Strategie, die der Funktion ähnelt, die zur Initialisierung von Werten verwendet wird. Mal sehen, wie man es benutzt.
Zunächst müssen wir den Cache initialisieren:
LoadingCache <string, dataObject> cache = caffein.newbuilder () .maximumsize (100) .expreaAnrite (1, timeUnit.minutes) .build (k -> dataObject.get ("Daten für" + k));Jetzt können wir die GET -Methode verwenden, um den Wert abzurufen:
DataObject dataObject = cache.get (Schlüssel); Assertnotnull (DataObject); AssertEquals ("Daten für" + Schlüssel, dataObject.getData ());Wir können auch die Getall -Methode verwenden, um eine Reihe von Werten zu erhalten:
Karte <string, dataObject> dataObjectmap = cache.getall (arrays.aslist ("a", "b", "c")); Assertequals (3, DataObjectMap.size ());Rufen Sie Werte aus der zugrunde liegenden Backend -Initialisierungsfunktion ab, die an die Build -Methode übergeben wurde. Dies ermöglicht die Verwendung von Cache als Hauptfassade des Zugriffs von Werten.
3.3. Asynchrone Beladung
Diese Richtlinie macht dasselbe wie zuvor, führt jedoch die Operation asynchron aus und gibt eine vervollständigbare Future zurück, die den Wert enthält:
AsyncloadingCache <string, dataObject> cache = caffein.newbuilder () .maximumsize (100) .expreaAnRWrite (1, TimeUnit.minutes) .buildasync (k -> DataObject.get ("Daten für" + k));Wir können die Get and Getall -Methoden auf die gleiche Weise verwenden, wobei wir berücksichtigen, dass sie eine vollständige Future zurückgeben:
String key = "a"; Cache.get (Schlüssel) .Denaccept (DataObject -> {AssertNotNull (DataObject); AssertEquals ("Daten für" + Schlüssel, DataObject.getData ());}); cache.getall (arrays.aslist ("a", "b", "c")) .Denaccept (DataObjectMap -> assertequals (3, dataObjectmap.size ());CompleteFuture hat viele nützliche APIs, und Sie können in diesem Artikel mehr erzielen.
4. Wertwiederherstellung
Koffein verfügt über drei Wertwiederherstellungsstrategien: Größenbasierte, zeitbasierte und referenzbasierte.
4.1. Recycling basierend auf der Größe
Diese Recyclingmethode geht davon aus, dass Recycling auftritt, wenn die konfigurierte Cache -Größenbeschränkung überschritten wird. Es gibt zwei Möglichkeiten, die Größe zu erhalten: Zählen Sie das Objekt im Cache oder das Gewicht.
Lassen Sie uns sehen, wie Objekte im Cache berechnet werden. Wenn der Cache initialisiert wird, entspricht seine Größe Null:
LoadingCache <string, dataObject> cache = caffein.newbuilder () .maximumsize (1) .build (k -> dataObject.get ("Daten für" + k)); AssertEquals (0, cache.estimatedSize ());Wenn wir einen Wert hinzufügen, nimmt die Größe erheblich zu:
cache.get ("a"); assertequals (1, cache.testimatedSize ());Wir können dem Cache den zweiten Wert hinzufügen, wodurch der erste Wert gelöscht wird:
Cache.get ("B"); Cache.CleanUp (); assertequals (1, cache.testimatedSize ());Es ist erwähnenswert, dass wir die Reinigungsmethode nennen, bevor wir die Cache -Größe erhalten. Dies liegt daran, dass das Cache -Recycling asynchron ausgeführt wird und dieser Ansatz hilft, auf das Recycling abzuschließen.
Wir können auch eine Wiegenfunktion übergeben, um die Cache -Größe zu erhalten:
LoadingCache <string, dataObject> cache = caffein.newbuilder () .maximumgewicht (10) .Wichter ((k, v) -> 5) .build (k -> dataObject.get ("Daten für" + k)); AssertEquals (0, cache.estimatedSize ()); cache.get ("a"); assertequals (1, cache.testimatedSize ()); Cache.get ("B"); assertequals (2, cache.estimatedSize ());Wenn das Gewicht 10 überschreitet, wird der Wert aus dem Cache gelöscht:
Cache.get ("C"); Cache.CleanUp (); assertequals (2, cache.estimatedSize ());4.2. Basierend auf der Zeitwiederherstellung
Diese Recyclingstrategie basiert auf der Ablaufzeit des Eintrags, und es gibt drei Typen:
Konfigurieren wir die Verfallsrichtlinie nach dem Zugriff mithilfe der Verfassungsabzug-Methode:
LoadingCache <String, DataObject> Cache = Coffein.newbuilder () .expreaNAccess (5, TimeUnit.minutes) .build (k -> dataObject.get ("Daten für" + k));Um die Verfallsrichtlinie nach dem Schreiben zu konfigurieren, verwenden wir die Versiegelungsmethode:
cache = Coffein.newbuilder () .expreaAnWrite (10, TimeUnit.seconds) .WeakKeys () .WeakValues () .build (k -> dataObject.get ("Daten für" + k));Um eine benutzerdefinierte Richtlinie zu initialisieren, müssen wir die Ablaufschnittstelle implementieren:
Cache = Coffein.Newbuilder (). Ablauf (Neue Ablauf <String, DataObject> () {@Override public Long Excireathercreate (String -Schlüssel, DataObject Value, Long Currentime) {return value.getData (). CurrentDuration;4.3. Recycling basierend auf der Referenz
Wir können den Cache konfigurieren, um die Müllsammlung von zwischengespeicherten Schlüsselwerten zu ermöglichen. Dazu konfigurieren wir Schlüssel und Wert als schwache Referenzen und können nur weiche Referenzen für die Müllsammlung konfigurieren.
Wenn es keine starken Hinweise auf das Objekt gibt, kann die Verwendung von WeaCrefence die Müllsammlung von Objekten ermöglichen. Mit Softrreference ermöglicht Objekte, Müll zu sammeln, basierend auf der globalen Richtlinie der JVM, die am wenigsten reduziert werden. Weitere Informationen zu Java -Zitaten finden Sie hier.
Wir sollten jede Option mit Coffein.Weakkeys (), Coffein.WeakValues () und Coffein.softValues () aktivieren:
LoadingCache <string, dataObject> cache = coffein.newbuilder () .expreaNWrite (10, TimeUnit.seconds) .WeakKeys () .WeakValues () .build (k -> DataObject.get ("Daten für" + k)); Cache = Coffein.newbuilder () .expreaAnWrite (10, TimeUnit.seconds) .SoftValues () .build (k -> dataObject.get ("Daten für" + k));5. Aktualisieren
Der Cache kann so konfiguriert werden, dass der Eintrag nach einem definierten Zeitraum automatisch aktualisiert wird. Sehen wir uns an, wie Sie die RefreshafterWrite -Methode verwenden:
Caffein.newbuilder () .refreshafterWrite (1, TimeUnit.minutes) .build (k -> dataObject.get ("Daten für" + k));Hier sollten wir den Unterschied zwischen Ablauf und Aktualisierung verstehen. Wenn ein abgelaufener Eintrag angefordert wird, blockiert die Ausführung, bis die Build -Funktion den neuen Wert berechnet.
Wenn der Eintrag jedoch aktualisiert werden kann, gibt der Cache einen alten Wert zurück und lädt den Wert asynchron neu.
6. Statistik
Koffein hat eine Möglichkeit, die Cache -Nutzung aufzuzeichnen:
LoadingCache <string, dataObject> cache = coffein.newbuilder () .maximumsize (100) .recordstats () .build (k -> dataObject.get ("Daten für" + k)); cache.get ("a"); cache.get ("a"); Assertequals (1, cache.stats (). HitCount ()); Assertequals (1, cache.stats (). MissCount ());Wir können auch in RecordStats -Lieferanten übergeben, um eine Implementierung von StatsCounter zu erstellen. Dieses Objekt wird bei jeder statistischen Änderung vorangetrieben.
7. Schlussfolgerung
In diesem Artikel sind wir mit der Koffein -Cache -Bibliothek von Java vertraut. Wir haben gesehen, wie man den Cache konfiguriert und füllt und wie die entsprechenden Ablauf- oder Aktualisierungsrichtlinien basierend auf unseren Anforderungen ausgewählt werden.
Der Quellcode für die Beispiele in diesem Artikel finden Sie in GitHub.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.