Maison >Java >javaDidacticiel >ConcurrentModificationException en utilisant Iterator en Java

ConcurrentModificationException en utilisant Iterator en Java

DDD
DDDoriginal
2025-02-07 11:18:10766parcourir

ConcurrentModificationException while using Iterator in 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:

  • Modification pendant l'itération: l'itérateur n'est pas conçu pour une modification simultanée.
  • Itérateurs de faillite: L'Itérateur utilise un drapeau interne (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:

  1. Initialisation: Créer un ArrayList.
  2. Population: Ajouter des éléments au ArrayList.
  3. itération: Obtenez un itérateur en utilisant list.iterator().
  4. Modification: À l'intérieur de la boucle d'itération, modifiez le ArrayList (par exemple, ajouter ou supprimer les éléments).
  5. Exception: Le 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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn