2016-08-31 2 views
0

Ich weiß, dass Guava Cache ermöglicht einzelne Caches mit einer Ablaufzeit konfiguriert werden. Benötigt Guava dies mithilfe eines Timers, der nach einer konfigurierten Anzahl von Sekunden aufwacht, um den Cache ungültig zu machen?Wie funktioniert der Ablauf des zeitgesteuerten Caches?

Ich habe eine Transaktion, die lange läuft. Was auch immer zu Beginn der Transaktion im Cache ist, möchte ich bis zum Ende der Transaktion fortsetzen. Selbst wenn die Anzahl der Sekunden der Gültigkeit eines Caches während der Transaktion abgelaufen ist, sollten die Werte, auf die vom Cache zugegriffen wird, intakt bleiben, bis das Ende der Transaktion erreicht ist. Ist das in Guava möglich?

Danke,
Yash

Antwort

1

Von When Does Cleanup Happen? · CachesExplained · google/guava Wiki:

mit CacheBuilder gebaut Caches nicht Bereinigung durchführen und Werte zu vertreiben "automatisch" oder sofort nach einem Wert abläuft, oder irgendetwas von die Sorte. Stattdessen führt es kleine Wartungsaufgaben während Schreiboperationen aus oder während gelegentlicher Lesevorgänge, wenn Schreibvorgänge selten sind.

Der Grund hierfür ist wie folgt: Wenn wir kontinuierlich Cache Wartung durchführen wollten, würden wir einen Thread erstellen müssen, und seine Operationen mit Benutzeroperationen für gemeinsame Sperren würde konkurrieren. Darüber hinaus beschränken einige Umgebungen die Erstellung von Threads , die CacheBuilder in dieser Umgebung unbrauchbar machen würde.

Stattdessen legen wir die Wahl in Ihre Hände. Wenn Ihr Cache High-Throughput ist, müssen Sie sich nicht darum kümmern, die Cache Wartung durchzuführen, um abgelaufene Einträge und ähnliches zu bereinigen. Wenn Ihr Cache nur selten schreibt und Sie nicht möchten, Cache zu blockieren, möchten Sie möglicherweise einen eigenen Wartungs-Thread erstellen, der in regelmäßigen Abständen Cache.cleanUp() aufruft.

Wenn Sie regelmäßig die Cache-Pflege für einen Cache planen möchten, die nur selten schreibt hat, planen nur die Wartung mit ScheduledExecutorService.

Als solcher, wenn Sie nur tun, liest man „könnte“ gut sein, wenn Sie ein Cache.cleanUp() tun kurz vor und nach der Transaktion, aber es gibt immer noch keine Garantie.

Anstatt jedoch zu erzwingen, dass Objekte im Cache verbleiben, können Sie stattdessen Elemente einfach in einen anderen Cache/Map mithilfe einer removalListener räumen. Wenn Sie dann lesen, müssen Sie zunächst den Cache überprüfen und dann Überprüfen Sie die Artikel, die während der langwierigen Transaktion gelöscht wurden.

Das Folgende ist ein stark vereinfachte Beispiel:

Map<Integer, String> evicted = new ConcurrentHashMap<>(); 
Cache<Integer, String> cache = CacheBuilder.newBuilder() 
     .expireAfterAccess(2, SECONDS) 
     .removalListener((RemovalListener<Integer, String>) notification -> 
       evicted.put(notification.getKey(), notification.getValue())) 
     .build(); 
assert evicted.size() == 0 && cache.size() == 0; 
cache.put(0, "a"); 
cache.put(1, "b"); 
cache.put(2, "c"); 
assert evicted.size() == 0 && cache.size() == 3; 
sleepUninterruptibly(1, SECONDS); 
assert evicted.size() == 0 && cache.size() == 3; 
cache.put(3, "d"); 
assert evicted.size() == 0 && cache.size() == 4; 
sleepUninterruptibly(1, SECONDS); 
cache.cleanUp(); 
assert evicted.size() == 3 && cache.size() == 1; 
Integer key = 2; 
String value; 
{ 
    value = cache.getIfPresent(key); 
    if (value == null) value = evicted.get(key); 
} 
assert Objects.equals(value, "c"); 

Ihr eigentlicher Code benötigen würde bedingt put in evicted, clean-up evicted, verwaltet mehrere evicted Objekte, wenn Ihr Lauf lang laufende Transaktionen gleichzeitig oder Verwendung ein gemeinsamer Cache zwischen den Threads mit einer anderen Eviction-Strategie, etc., aber hoffentlich zeigt dies die Idee ausreichend, um Ihnen den Einstieg zu erleichtern.

+0

Ich hoffte auf etwas, das eingebaut ist, mit dem Sie die automatische Räumung verhindern können, während eine Transaktion läuft. – Yash

+0

Richtig, ich habe es nicht explizit gesagt, aber von dem, was ich sagen kann, gibt es keine solche Funktion eingebaut. – mfulton26