Gibt es java.util.concurrent Äquivalent für WeakHashMap?
-
20-09-2019 - |
Frage
Kann der Code das folgende Stück neu geschrieben werden, w / o noch mit Collections.synchronizedMap()
Korrektheit bei Gleichzeitigkeit beibehalten?
Collections.synchronizedMap(new WeakHashMap<Class, Object>());
d. da etwas von java.util.concurrent man kann stattdessen verwenden? Beachten Sie, dass nur Ersatz mit
new ConcurrentHashMap<Class, Object>(new WeakHashMap<Class, Object>()));
offensichtlich nicht funktionieren
Lösung
Guava 's CacheBuilder -Klasse können Sie dies einfach tun.
CacheBuilder.newBuilder().weakKeys().build()
Beachten Sie, dass dieser Schlüssel Gleichheit Semantik ändert ==
statt .equals()
zu sein, die nicht Sache in Ihrem Fall Class
Instanzen verwenden, aber ein potenzielles pitfall.
Andere Tipps
Ich glaube nicht, es gibt. In der Tat schlägt die javadoc mit Collections.synchronizedMap ()
„Wie die meisten Collection-Klassen, ist diese Klasse nicht synchronisiert. Ein synchronisierter WeakHashMap aufgebaut werden kann, die Collections.synchronizedMap-Methode.“
Cafeine ist ein beliebter Konkurrent von Guava-Cache.
- keys automatically wrapped in weak references
- values automatically wrapped in weak or soft references
Nutzung:
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.weakKeys()
.weakValues()
.build(key -> createExpensiveGraph(key));
Hat den WeakHashMap in einer synchronisierten Karte Einwickeln noch Arbeit richtig für das, was wollen Sie den Garbage Collector kann zu tun, da die weakreferences direkt zu jeder Zeit ändern, unter Umgehung des synchronisierte Karte Wrapper? Ich denke, WeakHashMap funktioniert nur wirklich in einem Single-Threaded-Modell.
Wie bereits erwähnt, in der Dokumentation WeakHashMap unter https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html speziell sagt:
"Ein synchronisierter WeakHashMap kann unter Verwendung konstruiert die Collections.synchronizedMap Methode "
Was mir bedeutet, dass diese Technik muss Arbeit im Tandem mit dem Verhalten des Garbage Collector (es sei denn, die Dokumentation ist fehlerhaft!)
Wenn Sie mit Java 7 und höher, dieser Anwendungsfall in einem Thread-sichere Weise mit ClassValue
https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html Wenn Sie die Verwendung von remove
erfordern, sorgfältig über Gleichzeitigkeit denken und das Dokument gründlich lesen.
Wenn Sie mit Java 6 oder darunter. Nein, Sie müssen eine WeakHashMap synchronisieren.
Hat der WeakHashMap in einer synchronisierten Karte Einwickeln noch korrekt arbeiten, was Sie tun wollen, da der Garbage Collector das ändern kann direkt zu jeder Zeit weakreferences, Wrapper die synchronisierte Karte umgehen? Ich denke, WeakHashMap nur dann wirklich in einem einzigen Gewindemodell funktioniert.