Wie kann ich eine gleichzeitige Listeninstanz erstellen, in der ich über den Index auf Elemente zugreifen kann? Verfügt das JDK über Klassen oder Factory-Methoden, die ich verwenden kann?
java
list
concurrency
AlikElzin-Kilaka
quelle
quelle
List
die des Originals vorschlugen sagt ist eine Anforderung, die als Vandalismus gilt. Ein Moderator hat die Frage bereits gesperrt, weil sich die Leute beschweren, dass die Antworten diese zerstörte Version der Frage nicht beantworten.locked
/closed
/ Vorheriger KommentarAntworten:
In java.util.concurrent gibt es eine gleichzeitige Listenimplementierung . Insbesondere CopyOnWriteArrayList .
quelle
Wenn Sie keinen indexbasierten Zugriff benötigen und nur die Eigenschaften einer Liste beibehalten möchten, die die Einfügungsreihenfolge beibehalten, können Sie eine java.util.concurrent.ConcurrentLinkedQueue in Betracht ziehen . Da Iterable implementiert ist, können Sie nach dem Hinzufügen aller Elemente den Inhalt mithilfe der erweiterten Syntax durchlaufen:
quelle
:
) foreach heißt: docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.htmlSie können Collections.synchronizedList (List) sehr gut verwenden, wenn Sie lediglich eine einfache Aufrufsynchronisierung benötigen:
quelle
synchronizedList
ist "synchronisiert", aber nicht "gleichzeitig". Ein grundlegendes Problem ist, dass viele Listenoperationen - die indexbasiert sind - selbst nicht atomar sind und Teil eines größeren Konstrukts des gegenseitigen Ausschlusses sein müssen.Vector
ist eher unkompliziert alsCollections.synchronizedList(new ArrayList<Object>())
.Da das Erfassen der Position und das Abrufen des Elements von der angegebenen Position natürlich eine gewisse Sperrung erfordert (die Liste kann keine strukturellen Änderungen zwischen diesen beiden Operationen aufweisen).
Die Idee einer gleichzeitigen Sammlung besteht darin, dass jede Operation für sich atomar ist und ohne explizite Sperrung / Synchronisation ausgeführt werden kann.
Daher ist es in einer Situation, in der ein gleichzeitiger Zugriff erwartet wird, nicht sehr sinnvoll , das Element
n
von einer bestimmtenList
als atomare Operation an Position zu bringen.quelle
Sie haben folgende Möglichkeiten:
Collections.synchronizedList()
: Sie jede wickeln könnenList
Implementierung (ArrayList
,LinkedList
oder eine 3rd-Party - Liste). Der Zugriff auf jede Methode (Lesen und Schreiben) wird mit geschütztsynchronized
. Wenn Sie dieiterator()
for-Schleife verwenden oder erweitern, müssen Sie sie manuell synchronisieren. Während der Iteration werden andere Threads selbst beim Lesen vollständig blockiert. Sie können auch separat für jede synchronisierenhasNext
undnext
Anrufe, aber dannConcurrentModificationException
sind möglich.CopyOnWriteArrayList
: Es ist teuer zu ändern, aber ohne Wartezeit zu lesen. Iteratoren werfen nieConcurrentModificationException
, sie geben zum Zeitpunkt der Iteratorerstellung einen Schnappschuss der Liste zurück, selbst wenn die Liste während der Iteration von einem anderen Thread geändert wird. Nützlich für selten aktualisierte Listen. Massenoperationen wieaddAll
werden für Updates bevorzugt - das interne Array wird weniger oft kopiert.Vector
: sehr ähnlichsynchronizedList
, aber die Iteration ist auch synchronisiert. Iteratoren können jedoch auslösenConcurrentModificationException
, wenn der Vektor während der Iteration von einem anderen Thread geändert wird.Andere Optionen:
Collections.unmodifiableList()
: sperrenfrei, threadsicher, aber nicht veränderbarQueue
oderDeque
könnte eine Alternative sein, wenn Sie nur am Ende der Liste hinzufügen / entfernen und die Liste iterieren. Es gibt keinen Zugriff per Index und kein Hinzufügen / Entfernen an beliebigen Stellen. Sie haben mehrere gleichzeitige Implementierungen mit besserer Leistung und besserem gleichzeitigen Zugriff, aber dies geht über den Rahmen dieser Frage hinaus. Sie können sich auch JCTools ansehen , die leistungsfähigere Warteschlangenimplementierungen enthalten, die auf einzelne Verbraucher oder einzelne Hersteller spezialisiert sind.quelle
CopyOnWriteArrayList ist eine gleichzeitige Alternative der synchronisierten List implementiert die List-Schnittstelle und ist Teil des Pakets java.util.concurrent und eine thread-sichere Sammlung.
CopyOnWriteArrayList ist ausfallsicher und löst keine ConcurrentModificationException aus, wenn die zugrunde liegende CopyOnWriteArrayList während der Iteration geändert wird. Verwenden Sie eine separate Kopie von ArrayList.
Dies ist normalerweise zu kostspielig, da bei jedem Aktualisierungsvorgang eine geklonte Kopie erstellt wird. CopyOnWriteArrayList ist die beste Wahl nur für häufige Lesevorgänge.
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList.html
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
quelle