Mon pool de threads a un nombre fixe de threads. Ces threads ont besoin d' écrire et de lire fréquemment à partir d'une liste partagée.
Alors, quelle structure de données (il vaut mieux être une liste, doit être sans moniteur) dans le java.util.concurrent
package est la meilleure dans ce cas?
java
concurrency
象 嘉 道
la source
la source
List
.ConcurrentModificationException
peut ne pas venir d'un problème de synchronisation; il survient également par exemple dans une boucle for sur une collection où vous essayez de supprimer un élément de la collection.Vector
?Réponses:
La seule
List
implémentation dansjava.util.concurrent
est CopyOnWriteArrayList . Il y a aussi l'option d'une liste synchronisée comme le mentionne Travis Webb.Cela dit, êtes-vous sûr que vous en avez besoin pour être un
List
? Il y a beaucoup plus d'options pour lesQueue
s etMap
s simultanés (et vous pouvez faireSet
s à partir deMap
s), et ces structures ont tendance à être les plus logiques pour la plupart des types de choses que vous souhaitez faire avec une structure de données partagée.Pour les files d'attente, vous disposez d'un grand nombre d'options et celle qui est la plus appropriée dépend de la manière dont vous devez l'utiliser:
la source
CopyOnWriteArrayList
a l'inconvénient d'être très coûteux en écriture (mais bon marché en lecture). Si vous faites beaucoup d'écritures, vous êtes mieux avec une liste synchronisée ou une file d'attente.Toute collection Java peut être rendue sûre pour les threads comme ceci:
List newList = Collections.synchronizedList(oldList);
Ou pour créer une toute nouvelle liste thread-safe:
List newList = Collections.synchronizedList(new ArrayList());
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
la source
ConcurrentHashMap
même s'il existe uneCollections.synchronizedMap
méthode.ConcurrentHashMap
. Les détails de l'implémentation de la synchronisation sont différents. l'utilisation dessynchronized
méthodes enCollections
fait simplement envelopper la classe dans un moniteur Java.ConcurrentHashMap
utilise des fonctionnalités de concurrence plus intelligentes.Si la taille de la liste est fixe, vous pouvez utiliser un AtomicReferenceArray . Cela vous permettrait d'effectuer des mises à jour indexées sur un emplacement. Vous pouvez écrire une vue de liste si nécessaire.
la source
Vous voudrez peut-être regarder ConcurrentDoublyLinkedList écrit par Doug Lea sur la base de "A Practical Lock-Free Double-Linked List" de Paul Martin. Il n'implémente pas l'interface java.util.List, mais propose la plupart des méthodes que vous utiliseriez dans une liste.
Selon le javadoc:
la source
ConcurrentLinkedQueue
utilise une file d'attente sans verrouillage (basée sur la nouvelle instruction CAS ).la source
List
interface.List.set(int index, Object element)
avec ConcurrentLinkedQueue?List
méthodes spécifiques ne seront pas implémentables en utilisant unQueue
(ajouter / définir à un index spécifique, par exemple) ou peuvent en quelque sorte être implémentées mais seront inefficaces (extraites d'un index). Donc je ne pense pas que vous puissiez vraiment l'envelopper. Cela dit, je pense que la suggestion d'unQueue
est bien puisque le PO n'a pas vraiment expliqué pourquoi ils ont besoin d'unList
.Si set est suffisant, ConcurrentSkipListSet peut être utilisé. (Son implémentation est basée sur ConcurrentSkipListMap qui implémente une liste à sauter .)
Le coût en temps moyen prévu est log (n) pour les opérations contenant, ajouter et supprimer; la méthode de taille n'est pas une opération à temps constant.
la source