Mehrere Threads, die über dieselbe Map iterieren

8

Ich habe kürzlich ein paralleles Programm in Java geschrieben und bin auf das dumme Dilemma gestoßen: Angenommen, Sie haben eine globale Datenstruktur, die Teil einer normalen, nicht synchronisierten, nicht-parallelen Bibliothek wie HashMap ist. Ist es in Ordnung, mehreren Threads zu erlauben, durch die Sammlung zu iterieren (nur Lesen, keine Modifikationen), vielleicht in verschiedenen verschachtelten Perioden, d. H. Thread1 könnte halbwegs durch iterieren sein, wenn thread2 seinen Iterator auf derselben Karte bekommt?

    
Bober02 08.03.2012, 10:32
quelle

4 Antworten

12

Es ist OK. Die Fähigkeit, dies zu tun, ist der Grund, eine solche Schnittstelle als Iterator zu erstellen. Jeder Thread, der über eine Sammlung iteriert, hat seine eigene Iteratorinstanz, die ihren Status enthält (z. B. wo Sie sich gerade in Ihrem Iterationsprozess befinden).

Dadurch können mehrere Threads gleichzeitig über dieselbe Sammlung iterieren.

    
AlexR 08.03.2012, 10:36
quelle
7

Es sollte in Ordnung sein, solange es keine Autoren gibt.

Dieses Problem ähnelt der Leser-Schreiber-Sperre , wo mehrere Leser aus den Daten lesen dürfen, aber nicht während der Zeit, in der ein Schreiber die Sperre dafür "hat". Es gibt kein Problem mit dem gemeinsamen Zugriff für mehrere Lesevorgänge gleichzeitig. [Datenrennen kann nur auftreten, wenn Sie mindestens einen Schreibvorgang haben ].

    
amit 08.03.2012 10:36
quelle
4

Probleme treten nur auf, wenn Sie gleichzeitige Änderungen an einer Datenstruktur versuchen.

Wenn beispielsweise ein Thread über den Inhalt einer Map iteriert und ein anderer Thread Elemente aus dieser Sammlung löscht, werden Sie auf ernsthafte Probleme stoßen.

Wenn Sie einige Threads benötigen, um diese Sammlung sicher zu ändern, stellt Java entsprechende Mechanismen zur Verfügung, nämlich ConcurrentHashMap.

ConcurrentHashMap in Java?

Es gibt auch Hashtable, die dieselbe Schnittstelle wie HashMap hat, aber synchronisiert ist, obwohl ihre Verwendung derzeit nicht empfohlen wird (veraltet), da ihre Leistung leidet, wenn die Anzahl der Elemente größer wird (im Vergleich zu ConcurrentHashMap, die dies nicht tut) müssen die gesamte Sammlung sperren).

Wenn Sie eine Sammlung haben, die nicht synchronisiert ist und mehrere Threads zum Lesen und Schreiben benötigen, können Sie Collections.synchronizedMap (Map) verwenden, um eine synchronisierte Version zu erhalten.

    
pcalcao 08.03.2012 10:35
quelle
2

Die obigen Antworten sind sicherlich ein guter Rat. Wenn Sie Java mit parallelen Threads schreiben, müssen Sie sich keine Gedanken darüber machen, dass mehrere Threads diese Struktur gleichzeitig lesen, solange Sie keine Datenstruktur ändern.

Sollten Sie in Zukunft ein ähnliches Problem haben, außer dass die globale Datenstruktur gleichzeitig geändert werden könnte, würde ich vorschlagen, eine Java-Klasse zu schreiben, die alle Threads verwenden, um auf die Struktur zuzugreifen und sie zu ändern. Diese Klasse könnte ihre eigene Gleichzeitigkeitsmethodologie implementieren, indem sie entweder synchronisierte Methoden oder Sperren verwendet. Das Java-Tutorial hat eine sehr gute Erklärung für die Nebenläufigkeitsmechanismen von Java. Ich habe das persönlich gemacht und es ist ziemlich geradlinig.

    
Howard Schutzman 08.03.2012 16:51
quelle

Tags und Links