399 Stimmen

Gibt es eine gleichzeitige Liste im JDK von Java?

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?

271voto

Matt Passell Punkte 4187

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
}

228voto

Es gibt eine gleichzeitige Listenimplementierung in java.util.concurrent . CopyOnWriteArrayList im Besonderen.

175voto

Yanick Rochon Punkte 47683

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>());

62voto

Joachim Sauer Punkte 290477

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.

56voto

Oliv Punkte 9469

Sie haben folgende Möglichkeiten:

  • Collections.synchronizedList() : Sie können jede List Implementierung ( ArrayList , LinkedList oder eine Liste eines Drittanbieters). Der Zugang zu jeder Methode (Lesen und Schreiben) wird geschützt durch synchronized . Bei der Verwendung von iterator() 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 synchronisieren hasNext y next Anrufe, aber dann ConcurrentModificationException ist möglich.

  • CopyOnWriteArrayList : Es ist teuer zu ändern, aber ohne Wartezeit zu lesen. Iteratoren werfen niemals ConcurrentModificationException 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 wie addAll werden für Aktualisierungen bevorzugt - das interne Array wird weniger oft kopiert.

  • Vector : sehr gerne synchronizedList(new ArrayList<>()) aber auch die Iteration wird synchronisiert. Allerdings können Iteratoren ConcurrentModificationException wenn der Vektor während der Iteration von einem anderen Thread geändert wird.

Andere Optionen:

  • Queue o Deque 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 jede List bieten kann. Schauen Sie sich "All Known Implementing Classes" in der Warteschlange javadoc sind die Implementierungen, die in der java.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 änderbar
  • List.of & List.copyOf : Eine weitere nicht änderbare Liste in Java 9 und höher.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X