Comment puis-je créer une instance de liste simultanée, où je peux accéder aux éléments par index? Le JDK a-t-il des classes ou des méthodes d'usine que je peux utiliser?
java
list
concurrency
AlikElzin-kilaka
la source
la source
List
que l'original spécifiquement dit que c'est une exigence qui est considérée comme du vandalisme. Un modérateur a déjà verrouillé la question à cause des personnes qui se plaignent que les réponses ne répondent pas à cette version vandalisée de la question.locked
/closed
/ commentaire précédentRéponses:
Il existe une implémentation de liste simultanée dans java.util.concurrent . CopyOnWriteArrayList en particulier.
la source
Si vous ne vous souciez pas d'avoir un accès basé sur un index et que vous voulez simplement les caractéristiques préservant l'ordre d'insertion d'une liste, vous pouvez envisager un java.util.concurrent.ConcurrentLinkedQueue . Puisqu'il implémente Iterable, une fois que vous avez terminé d'ajouter tous les éléments, vous pouvez parcourir le contenu en utilisant la syntaxe améliorée pour:
la source
:
) s'appelle foreach: docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.htmlVous pouvez très bien utiliser Collections.synchronizedList (List) si tout ce dont vous avez besoin est une simple synchronisation d'invocation:
la source
synchronizedList
est "synchronisé" mais pas "simultané". Un problème fondamental que de nombreuses opérations List - qui sont basées sur un index - ne sont pas elles-mêmes atomiques et doivent faire partie d'une construction d'exclusion mutuelle plus large.Vector
est plus simple queCollections.synchronizedList(new ArrayList<Object>())
.Parce que l'acte d'acquérir la position et d'obtenir l'élément à partir de la position donnée nécessite naturellement un certain verrouillage (vous ne pouvez pas avoir la liste de changements structurels entre ces deux opérations).
L'idée même d'une collection simultanée est que chaque opération en elle-même est atomique et peut être effectuée sans verrouillage / synchronisation explicite.
Par conséquent, obtenir l'élément en position à
n
partir d'une donnée enList
tant qu'opération atomique n'a pas trop de sens dans une situation où un accès simultané est prévu.la source
Vous avez ces options:
Collections.synchronizedList()
: vous pouvez encapsuler n'importe quelleList
implémentation (ArrayList
,LinkedList
ou une liste tierce). L'accès à chaque méthode (lecture et écriture) sera protégé à l'aide desynchronized
. Lorsque vous utiliseziterator()
ou améliorez la boucle, vous devez synchroniser manuellement; lors de l'itération, les autres threads sont complètement bloqués, même en lecture. Vous pouvez également synchroniser séparément pour chacunhasNext
et lesnext
appels, maisConcurrentModificationException
c'est possible.CopyOnWriteArrayList
: c'est cher à modifier, mais sans attendre pour lire. Les itérateurs ne jettent jamaisConcurrentModificationException
, ils retournent un instantané de la liste au moment de la création de l'itérateur, même si la liste est modifiée par un autre thread pendant l'itération. Utile pour les listes rarement mises à jour. Les opérations en bloc commeaddAll
sont préférées pour les mises à jour - la matrice interne est copiée moins de fois.Vector
: très similairesynchronizedList
, mais l'itération est également synchronisée. Cependant, les itérateurs peuvent lancerConcurrentModificationException
, si le vecteur est modifié par un autre thread pendant l'itération.Autres options:
Collections.unmodifiableList()
: sans verrouillage, thread-safe, mais non modifiableQueue
ouDeque
peut être une alternative si vous ajoutez / supprimez uniquement à la fin de la liste et parcourez la liste. Il n'y a pas d'accès par index et pas d'ajout / suppression à des endroits arbitraires. Ils ont plusieurs implémentations simultanées avec de meilleures performances et un meilleur accès simultané, mais cela dépasse le cadre de cette question. Vous pouvez également jeter un œil à JCTools , ils contiennent des implémentations de files d'attente plus performantes spécialisées pour un seul consommateur ou un seul producteur.la source
CopyOnWriteArrayList est une alternative simultanée de List synchronise les implémentations de l'interface List et de sa partie du paquet java.util.concurrent et de sa collection thread-safe.
CopyOnWriteArrayList est à sécurité intégrée et ne lève pas ConcurrentModificationException lorsque CopyOnWriteArrayList sous-jacent est modifié pendant l'itération, utilisez une copie distincte d'ArrayList.
Ceci est généralement trop coûteux car le tableau de copie impliquait chaque opération de mise à jour, une copie clonée sera créée. CopyOnWriteArrayList est le meilleur choix uniquement pour les opérations de lecture fréquentes.
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
la source