Nicht direkt, da der schwache Wert Müll sein kann gesammelt sobald es keine starken Verweise mehr auf das Objekt gibt. Sie können jedoch einen ForwardingCache
verwenden, der durch zwei separate Caches, einen Puffer mit schwachem Wert und einen Cache mit zeitgesteuertem Ablauf unterstützt wird, so dass der zeitbasierte Cache einen starken Verweis auf das Objekt enthält und somit im Cache mit schwachem Wert bleibt . Es würde wie folgt aussehen:
public class WeakValuedExpiringCache<K, V> extends ForwardingCache<K, V> {
private final Cache<K, V> expiringCache;
private final Cache<K, V> weakCache;
public WeakValuedExpiringCache(CacheBuilder expiringSpec) {
expiringCache = expiringSpec.build();
weakCache = CacheBuilder.newBuilder().weakValues().build();
}
// weakCache is the canonical cache since it will hold values longer than
// expiration if there remain other strong references
protected Cache<K, V> delagate() {
return weakCache;
}
@override
public V get(K key, Callable<? extends V> valueLoader)
throws ExecutionException {
// repopulate the expiring cache if needed, and update the weak cache
V value = expiringCache.get(key, valueLoader);
weakCache.put(key, value); // don't call super.put() here
}
@Override
public void put(K key, V value) {
expiringCache.put(key, value);
super.put(key, value);
}
// Handle putAll(), cleanUp(), invalidate(), and invalidateAll() similarly
}
Sie können mit einem ForwardingLoadingCache
auch das gleiche tun, so wie .get()
oben sollten Sie den Wert aus dem expiringCache
und .put()
in die weakCache
in den entsprechenden Lademethoden laden .
Vielen Dank! Das ist perfekt. Und du hast in meine Frage gesehen, dass ich meinte, dass es keine weiteren Verweise auf den Wert BESIDES des Caches geben sollte. Ich hatte nicht gedacht, dass eine schwache Referenz gc niemals verhindern wird. – jacob