web-dev-qa-db-fra.com

Choisir la meilleure liste de simultanéité dans Java

Mon pool de threads a un nombre fixe de threads. Ces threads doivent fréquemment écrire et lire à partir d'une liste partagée.

Donc, quelle structure de données (mieux vaut être une liste, ne doit pas être surveillé) dans Java.util.concurrent Le forfait est-il préférable dans ce cas?

76
象嘉道

mieux valait être List

Le seulement List implémentation dans Java.util.concurrent est CopyOnWriteArrayList . Il existe également l'option d'une liste synchronisée mentionnée par Travis Webb.

Cela dit, êtes-vous sûr d’en avoir besoin pour être un List? Il y a beaucoup plus d'options pour Queues et Maps simultanés (et vous pouvez créer Sets à partir de Maps), et ces structures ont tendance à avoir le plus de sens pour la plupart des tâches que vous souhaitez effectuer avec une structure de données partagée.

Pour les files d'attente, vous avez un très grand nombre d'options et la plus appropriée dépend de la façon dont vous devez l'utiliser:

78
ColinD

N'importe quelle collection Java peut être faite pour être thread-safe comme ceci:

List newList = Collections.synchronizedList(oldList);

Ou pour créer une nouvelle liste fil-safe:

List newList = Collections.synchronizedList(new ArrayList());

http://download.Oracle.com/javase/6/docs/api/Java/util/Collections.html#synchronizedList (Java.util.List)

52
Travis Webb

Si la taille de la liste est corrigée, vous pouvez utiliser un AtomicReferenceArray . Cela vous permettrait d'effectuer des mises à jour indexées dans un emplacement. Vous pouvez écrire une vue de liste si nécessaire.

8
Ben Manes

Vous voudrez peut-être regarder ConcurrentDoublyLinkedList écrit par Doug Lea à partir de "Une liste pratique à double verrouillage sans verrouillage" 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:

Implémentation simultanée d'une liste liée de Deque (file d'attente à deux extrémités). Les opérations d'accès, de suppression et d'accès simultanées s'exécutent en toute sécurité sur plusieurs threads. Les itérateurs sont faiblement cohérent, retournant des éléments reflétant l’état de la deque à un moment donné ou depuis la création de l’itérateur. Ils ne lancent pas une exception ConcurrentModificationException et peuvent être exécutés simultanément avec d'autres opérations.

6
shams

ConcurrentLinkedQueue utilise une file d'attente sans verrouillage (basée sur le plus récent instruction CAS ).

3
eSniff

Si set est suffisant, ConcurrentSkipListSet peut être utilisé. (Son implémentation est basée sur ConcurrentSkipListMap qui implémente un liste de sauts .)

Le coût temporel moyen attendu est log (n) pour les opérations contient, ajoute et supprime; la méthode de la taille n'est pas une opération à temps constant.

1
anre