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

ConcurrentModificationException en utilisant Iterator en Java

DDD
Libérer: 2025-02-07 11:18:10
original
764 Les gens l'ont consulté

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:

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)
Copier après la connexion

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

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!
            }
        }
    }
}
Copier après la connexion

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()

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);
    }
}
Copier après la connexion

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!

Étiquettes associées:
Déclaration de ce site Web
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
Derniers numéros
Impossible d'installer Java
Depuis 1970-01-01 08:00:00
0
0
0
Java peut-il être utilisé comme backend du Web ?
Depuis 1970-01-01 08:00:00
0
0
0
Installer JAVA
Depuis 1970-01-01 08:00:00
0
0
0
Aide : Données chiffrées JAVA Décryptage PHP
Depuis 1970-01-01 08:00:00
0
0
0
Est-ce en langage Java ?
Depuis 1970-01-01 08:00:00
0
0
0
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal