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?
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 Queue
s et Map
s simultanés (et vous pouvez créer Set
s à partir de Map
s), 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:
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());
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.
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.
ConcurrentLinkedQueue
utilise une file d'attente sans verrouillage (basée sur le plus récent instruction CAS ).
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.