2012-05-14 4 views
10

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?

Antwort

6

Wenn Sie ReferenceQueue betrachten, werden Sie sehen, dass das Threading innerhalb der Plattform explizit unterstützt wird, da es besagt, dass die remove()-Methode blockiert, bis ein neuer Eintrag verfügbar ist.

Die synchronized Sie in WeakHashMap sehen, ist sicherzustellen, dass mehrere Threads Zugriff auf eine ReferenceQueue ordnungsgemäß synchronisiert sind.

Sie könnten diese verwandten bug at bugs.sun.com interessant finden.

Um Ihre Frage zu beantworten, denke ich, externe Synchronisation der ReferenceQueue ist nicht erforderlich, wenn Sie sicherstellen, es wird nur von einem einzigen Thread zugegriffen. Ich würde nicht verwenden (und kann mir keinen guten Grund vorstellen), eine einzige ReferenceQueue als Verbraucher aus mehreren Threads zu verwenden.

+0

+1 Netter Fund - Interessant, wie eine Lesemethode die Karte ändern kann. –

+1

@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

+0

@ John Vint zum Beispiel LinkedHashMap get ändert die Map, weil sie die Reihenfolge des Zugriffs speichert – gstackoverflow

Verwandte Themen