ich einen Blick auf den Quellcode für WeakHashMap
nehmen und stolperte über dieses:Sollte ich auf einer ReferenceQueue synchronisieren?
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null;) {
synchronized (queue) {
/* snip */
}
}
}
Warum funktioniert diese Methode synchronisieren auf dem ReferenceQueue
? WeakHashMap
nicht selbst machen Ansprüche Faden sicher zu sein:
Wie die meisten Collection-Klassen, ist diese Klasse nicht synchronisiert. Eine synchronisierte WeakHashMap kann mit der Collections.synchronizedMap-Methode erstellt werden.
Was mich dazu gebracht zu glauben, dass diese Implementierung Detail ist irgendwie den Faden Sicherheit des ReferenceQueue
selbst sorgen (da die GC aus eigenen Thread
Modifizierung wird). the documentation for ReferenceQueue
erwähnt jedoch nichts über Nebenläufigkeitsbedenken, und ein Blick auf den Quellcode für ReferenceQueue
zeigt, dass es nicht sogar auf sich selbst synchronisiert (es verwendet eine interne Sperre).
Warum wird WeakHashMap
synchronisiert auf ReferenceQueue
? Sollte ich jedes Mal, wenn ich es benutze, eine ReferenceQueue
synchronisieren?
+1 Netter Fund - Interessant, wie eine Lesemethode die Karte ändern kann. –
@andersoj Ahh, dieser Fehlerbericht macht es klar. Da der Aufruf von 'size' auf einer' WeakHashMap' die zugrundeliegende Karte verändern könnte, könnte ein Benutzer, der gleichzeitig 'size' auf einem aufruft, diesen möglicherweise beschädigen. Dieses Verhalten steht im Gegensatz zu den meisten (allen?) Anderen JDK 'Map'-Implementationen, die es mehreren Threads erlauben würden, ihre Inhalte ohne Probleme zu lesen, so dass sie beschlossen haben, die Klasse ein wenig Thread-sicher zu machen, um die Konsistenz mit dem' Karte' Spezifikation. – Jeffrey
@ John Vint zum Beispiel LinkedHashMap get ändert die Map, weil sie die Reihenfolge des Zugriffs speichert – gstackoverflow