Wie kann ich eine gleichzeitige Listeninstanz erstellen, bei der ich auf Elemente nach Index zugreifen kann? Verfügt das JDK über Klassen oder Fabrikmethoden, die ich verwenden kann?
Antworten
Zu viele Anzeigen?ConcurrentLinkedQueue
Wenn Sie sich nicht um einen indexbasierten Zugriff kümmern und nur die Einfüge-Reihenfolge-erhaltenden Eigenschaften einer Liste haben wollen, könnten Sie eine java.util.concurrent.ConcurrentLinkedQueue
. Da es Iterable implementiert, können Sie, sobald Sie alle Elemente hinzugefügt haben, mit der erweiterten for-Syntax eine Schleife über den Inhalt ziehen:
Queue<String> globalQueue = new ConcurrentLinkedQueue<String>();
//Multiple threads can safely call globalQueue.add()...
for (String href : globalQueue) {
//do something with href
}
Es gibt eine gleichzeitige Listenimplementierung in java.util.concurrent . CopyOnWriteArrayList im Besonderen.
Haftungsausschluss : Diese Antwort wurde 2011 veröffentlicht, also vor JDK 5 und vor sehr fortschrittlichen und optimalen gleichzeitigen APIs. Während also die folgende volonté arbeiten, ist dies nicht die beste Option.
Sie können sehr wohl verwenden Collections.synchronizedList(Liste) wenn Sie nur eine einfache Synchronisierung von Aufrufen benötigen:
List<Object> objList = Collections.synchronizedList(new ArrayList<Object>());
Denn der Akt des Erfassens der Position und des Abrufs des Elements von der gegebenen Position erfordert natürlich ein gewisses Sperren (die Liste darf zwischen diesen beiden Operationen keine strukturellen Änderungen aufweisen).
Der eigentliche Gedanke einer gleichzeitigen Auflistung ist, dass jeder Vorgang für sich genommen atomar ist und ohne explizite Sperrung/Synchronisierung durchgeführt werden kann.
Daher wird das Element an der Position n
von einer bestimmten List
als atomarer Vorgang ist in einer Situation, in der ein gleichzeitiger Zugriff erwartet wird, nicht sehr sinnvoll.
Sie haben folgende Möglichkeiten:
-
Collections.synchronizedList()
: Sie können jedeList
Implementierung (ArrayList
,LinkedList
oder eine Liste eines Drittanbieters). Der Zugang zu jeder Methode (Lesen und Schreiben) wird geschützt durchsynchronized
. Bei der Verwendung voniterator()
oder einer erweiterten for-Schleife, müssen Sie die gesamte Iteration manuell synchronisieren. Während der Iteration sind andere Threads vollständig blockiert, selbst beim Lesen. Sie können auch für jeden Thread separat synchronisierenhasNext
ynext
Anrufe, aber dannConcurrentModificationException
ist möglich. -
CopyOnWriteArrayList
: Es ist teuer zu ändern, aber ohne Wartezeit zu lesen. Iteratoren werfen niemalsConcurrentModificationException
geben sie einen Schnappschuss der Liste zum Zeitpunkt der Iteratorerstellung zurück, auch wenn die Liste während der Iteration von einem anderen Thread geändert wird. Nützlich für Listen, die nur selten aktualisiert werden. Bulk-Operationen wieaddAll
werden für Aktualisierungen bevorzugt - das interne Array wird weniger oft kopiert. -
Vector
: sehr gernesynchronizedList(new ArrayList<>())
aber auch die Iteration wird synchronisiert. Allerdings können IteratorenConcurrentModificationException
wenn der Vektor während der Iteration von einem anderen Thread geändert wird.
Andere Optionen:
Queue
oDeque
könnte eine Alternative sein, wenn Sie nur an den Enden der Liste hinzufügen/entfernen oder die Liste iterieren.Queue
erlaubt nur das Hinzufügen an einem Ende und das Entfernen am anderen Ende,Deque
ermöglicht das Hinzufügen und Entfernen an beiden Enden. Es gibt keinen Zugriff über einen Index. Es gibt mehrere Implementierungen mit besseren Gleichzeitigkeitseigenschaften als jedeList
bieten kann. Schauen Sie sich "All Known Implementing Classes" in der Warteschlange javadoc sind die Implementierungen, die in derjava.util.concurrent
Paket sind gleichzeitig. Sie können auch einen Blick werfen auf JCTools Sie enthält schnellere Warteschlangenimplementierungen, die auf einzelne Verbraucher oder einzelne Produzenten spezialisiert sind.Collections.unmodifiableList()
Wartefrei, thread-sicher, aber nicht änderbarList.of
&List.copyOf
: Eine weitere nicht änderbare Liste in Java 9 und höher.
- See previous answers
- Weitere Antworten anzeigen