Maison >Java >javaDidacticiel >ConcurrentModificationException en utilisant Iterator en Java
Dans les environnements Java multithread, tenter de modifier une collection tout en itérant dessus à l'aide d'un itérateur peut conduire à un ConcurrentModificationException
. Cette exception survient parce que l'état interne de la collection devient incohérent.
Voici un exemple illustrant l'exception:
<code class="language-java">Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:000) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:000) at com.journaldev.ConcurrentModificationException.ConcurrentModificationExceptionExample.main(ConcurrentModificationExceptionExample.java:00)</code>
Cette exception se produit dans ces conditions:
modCount
) pour détecter les modifications et lance l'exception. Algorithme pour reproduire l'exception
Cet algorithme montre comment déclencher un ConcurrentModificationException
en java:
ArrayList
. ArrayList
. list.iterator()
. ArrayList
(par exemple, ajouter ou supprimer les éléments). ConcurrentModificationException
est lancé lorsque l'itérateur détecte la modification. Exemple de code: déclenchant l'exception
<code class="language-java">import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ConcurrentModificationExample { public static void main(String[] args) { List<integer> myList = new ArrayList<>(); myList.add(1); myList.add(2); myList.add(3); Iterator<integer> iterator = myList.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); System.out.println("Value: " + value); if (value == 2) { myList.remove(value); // Modification during iteration! } } } }</integer></integer></code>
Ce code lancera un ConcurrentModificationException
car myList.remove(value)
modifie la liste pendant que l'itérateur le traverse.
Techniques de modification sûres
Pour éviter cette exception, utilisez ces approches:
Iterator.remove()
: Utilisez la méthode iterator.remove()
pour supprimer les éléments pendant l'itération. Cette méthode est sûre car elle est conçue pour fonctionner avec l'état interne de l'itérateur.
Copiez la liste: Créez une copie de la liste avant d'itérer et modifiez la copie.
Utilisez des collections simultanées: Pour les scénarios de modification simultanés, utilisez des collections de filetage comme CopyOnWriteArrayList
ou ConcurrentHashMap
.
Bloc synchronisé: Entrez l'itération et la modification dans un bloc synchronisé pour assurer la sécurité des filetages.
Exemple: Retrait sûr à l'aide de Iterator.remove()
<code class="language-java">import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class SafeRemovalExample { public static void main(String[] args) { List<integer> myList = new ArrayList<>(); myList.add(1); myList.add(2); myList.add(3); Iterator<integer> iterator = myList.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); System.out.println("Value: " + value); if (value == 2) { iterator.remove(); // Safe removal using iterator.remove() } } System.out.println(myList); } }</integer></integer></code>
Ce code révisé supprime en toute sécurité l'élément sans lancer l'exception. N'oubliez pas de choisir la technique appropriée en fonction de vos besoins spécifiques et de vos exigences de concurrence. L'utilisation de collections simultanées est généralement préférée pour les scénarios multithreads.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!