Mein Thread-Pool hat eine feste Anzahl von Threads. Diese Threads müssen häufig aus einer freigegebenen Liste schreiben und lesen .
Welche Datenstruktur (besser eine Liste, muss ohne Monitor sein) im java.util.concurrent
Paket ist in diesem Fall am besten?
java
concurrency
象 嘉 道
quelle
quelle
List
.ConcurrentModificationException
möglicherweise nicht auf ein Synchronisationsproblem zurückzuführen. Dies tritt beispielsweise auch in einer for-Schleife über einer Sammlung auf, in der Sie versuchen, ein Element aus der Sammlung zu entfernen.Vector
?Antworten:
Die einzige
List
Implementierung injava.util.concurrent
ist CopyOnWriteArrayList . Es gibt auch die Option einer synchronisierten Liste, wie Travis Webb erwähnt.Bist du sicher, dass du es brauchst, um ein zu sein
List
? Es gibt viel mehr Optionen für gleichzeitigeQueue
s undMap
s (und Sie könnenSet
s ausMap
s erstellen), und diese Strukturen sind für viele der Arten von Dingen, die Sie mit einer gemeinsam genutzten Datenstruktur ausführen möchten, am sinnvollsten.Für Warteschlangen stehen eine Vielzahl von Optionen zur Verfügung. Welche Option am besten geeignet ist, hängt davon ab, wie Sie sie verwenden müssen:
quelle
CopyOnWriteArrayList
hat den Nachteil, dass es beim Schreiben sehr teuer ist (aber für das Lesen billig). Wenn Sie viele Schreibvorgänge ausführen, sind Sie mit einer synchronisierten Liste oder einer Warteschlange besser dran.Jede Java-Sammlung kann wie folgt threadsicher gemacht werden:
List newList = Collections.synchronizedList(oldList);
Oder um eine brandneue thread-sichere Liste zu erstellen:
List newList = Collections.synchronizedList(new ArrayList());
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
quelle
ConcurrentHashMap
obwohl es eineCollections.synchronizedMap
Methode gibt.ConcurrentHashMap
. Die Details der Synchronisationsimplementierung sind unterschiedlich. Wenn Sie diesynchronized
Methoden in verwenden, wirdCollections
die Klasse im Grunde nur in einen Java-Monitor eingeschlossen.ConcurrentHashMap
Verwendet cleverere Parallelitätsfunktionen.Wenn die Größe der Liste festgelegt ist, können Sie ein AtomicReferenceArray verwenden . Auf diese Weise können Sie indizierte Aktualisierungen an einem Steckplatz durchführen. Bei Bedarf können Sie eine Listenansicht schreiben.
quelle
Vielleicht möchten Sie sich die ConcurrentDoublyLinkedList ansehen, die von Doug Lea basierend auf Paul Martins "A Practical Lock-Free Doubly-Linked List" geschrieben wurde. Die Schnittstelle java.util.List wird nicht implementiert, bietet jedoch die meisten Methoden, die Sie in einer Liste verwenden würden.
Laut dem Javadoc:
quelle
ConcurrentLinkedQueue
verwendet eine sperrfreie Warteschlange (basierend auf der neueren CAS-Anweisung ).quelle
List
Schnittstelle nicht implementiert .List.set(int index, Object element)
mit ConcurrentLinkedQueue implementieren ?List
spezifischen Methoden können entweder nicht mit a implementiert werdenQueue
(z. B. Hinzufügen / Festlegen an einem bestimmten Index) oder können implementiert werden, sind jedoch ineffizient (aus einem Index abrufen). Ich glaube also nicht, dass Sie es wirklich einpacken könnten. Trotzdem denke ich, dass der Vorschlag von aQueue
in Ordnung ist, da das OP nicht wirklich erklärt hat, warum sie a brauchenList
.Wenn set ausreichend ist, kann ConcurrentSkipListSet verwendet werden. (Die Implementierung basiert auf ConcurrentSkipListMap, die eine Überspringliste implementiert .)
Die erwarteten durchschnittlichen Zeitkosten sind log (n) für die Vorgänge zum Einschließen, Hinzufügen und Entfernen. Die Größenmethode ist keine Operation mit konstanter Zeit.
quelle