Contenu du cours
Multithreading en Java
Multithreading en Java
Collection Copy-On-Write
Nous avons exploré de nombreuses collections synchronisées ensemble, et si vous avez maîtrisé les autres, vous trouverez celle-ci encore plus simple.
Exemple de la vie réelle
Une application web qui utilise CopyOnWriteArrayList
pour stocker les abonnés aux événements. Plusieurs threads peuvent simultanément récupérer une liste des abonnés actuels pour les notifier des changements, tandis que d'autres threads peuvent ajouter ou supprimer des abonnés.
Différences par rapport à d'autres types
Les collections CopyOnWrite
créent une copie de la collection chaque fois qu'une modification est effectuée, garantissant que les opérations de lecture ne sont pas bloquées par les changements de données, offrant ainsi une sécurité des threads pour les lectures, bien que les opérations d'écriture ne soient pas sécurisées pour les threads car elles se produisent sur une copie distincte de la collection.
Vues CopyOnWrite :
Remarque
Comme nous pouvons le voir sur l'image, lors de l'ajout d'un nouvel élément, nous faisons une copie de cette structure de données, tous les threads qui travaillaient avec cette collection avant son changement continueront leur travail sans aucun problème, car ces changements n'affecteront pas la copie
CopyOnWrite
qu'ils utilisent !
CopyOnWriteArraySet
CopyOnWriteArraySet
est une implémentation thread-safe d'un ensemble basé sur CopyOnWriteArrayList
. Il assure la sécurité des threads en créant une nouvelle copie de l'ensemble de base chaque fois qu'un changement, tel que l'ajout ou la suppression d'éléments, se produit.
Cette approche est particulièrement utile lorsque l'ensemble est fréquemment lu et rarement modifié, car elle offre une vue cohérente de l'ensemble pour tous les threads sans nécessiter de synchronisation.
CopyOnWriteArrayList
CopyOnWriteArrayList
est une variante thread-safe de ArrayList
qui assure la sécurité des threads en créant une nouvelle copie du tableau sous-jacent chaque fois qu'il est modifié.
Ce design offre un itérateur tolérant aux pannes qui ne lance pas de ConcurrentModificationException
car il fonctionne sur un instantané du tableau pris au moment où l'itérateur a été créé. Il est le mieux adapté aux situations où les opérations de lecture sont beaucoup plus fréquentes que les opérations d'écriture, car le coût de la copie de l'ensemble du tableau à chaque écriture peut être considérable.
Exemple Pratique de Cas d'Utilisation
Méthodes de la collection CopyOnWrite
addIfAbsent(E e)
: Ajoute un élément à la liste uniquement s'il n'est pas déjà dans la liste/multiple.
Main
package com.example; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); // Attempt to add a duplicate element list.addIfAbsent("apple"); // This will not add "apple" again // Adding a new element list.addIfAbsent("orange"); // This will add "orange" System.out.println(list); // Output: [apple, banana, orange] } }
Dans cet exemple, "apple" n'est pas ajouté à nouveau car il existe déjà dans la liste. La méthode addIfAbsent()
empêche les entrées en double, maintenant l'unicité des éléments.
addAllAbsent(Collection<? extends E> c)
: Ajoute tous les éléments de la collection spécifiée à la liste/multiple, en ignorant les éléments déjà existants.
Main
package com.example; import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); List<String> newFruits = Arrays.asList("banana", "cherry", "date"); // Adding elements from the collection, ignoring duplicates list.addAllAbsent(newFruits); System.out.println(list); // Output: [apple, banana, cherry, date] } }
Dans cet exemple, "banana" est déjà présent dans la liste, donc addAllAbsent()
ne l'ajoutera pas à nouveau. La méthode garantit que seuls les éléments uniques de la collection fournie sont ajoutés à la liste.
Remarque
Toutes les autres méthodes des collections
CopyOnWrite
sont similaires à celles de leurs collections parentes; elles copient simplement l'état de la collection chaque fois que des modifications sont apportées.
Limitations et Avantages
😔Limitations:
Les collections CopyOnWrite
ont des limitations notables. Elles entraînent un coût mémoire en raison de la création d'une nouvelle copie de la collection chaque fois qu'un changement est effectué, ce qui peut être considérable. Cette conception les rend moins adaptées aux scénarios où des modifications fréquentes des données sont nécessaires.
💪Avantages:
D'un autre côté, les collections CopyOnWrite
offrent des avantages significatifs. Elles sont très efficaces pour la lecture de données dans un environnement multi-threadé. Ces collections fonctionnent exceptionnellement bien dans les situations où les opérations de lecture surpassent largement les opérations d'écriture, ce qui en fait un excellent choix pour de tels cas d'utilisation.
Remarque
Cependant, en raison du copiage à chaque changement, les collections
CopyOnWrite
peuvent consommer plus de mémoire et ne conviennent pas aux scénarios avec des opérations d'écriture fréquentes. Elles sont les plus efficaces lorsque les opérations de lecture prédominent sur les opérations d'écriture.
1. Que se passe-t-il lorsque vous appelez la méthode addIfAbsent(E e)
dans CopyOnWriteArrayList?
2. Pourquoi les collections CopyOnWrite
sont-elles particulièrement adaptées aux scénarios avec des lectures fréquentes et des modifications de données peu fréquentes ?
Merci pour vos commentaires !