IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

[Collection] ConcurrentModificationException - Conseils


Sujet :

Collection et Stream Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 31
    Points : 34
    Points
    34
    Par défaut [Collection] ConcurrentModificationException - Conseils
    Bonjour,

    Je rencontre un problème de ConcurrentModificationException dans le cas ci dessous.
    J'ai peut être trouvé une solution et je voudrais votre avis : est elle correcte ? y a t'il plus propre ?

    Ajout d'un Listener :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    public boolean addUpdateListener ( UpdateListener p_listener ) {
     
      ...
      if (!this.m_listeners.contains( p_listener )) {
     
          listenerAdded = this.m_listeners.add( p_listener );
     
      } else {
     
          ...
          listenerAdded = false;
      }
      ...
    }
    Notification des listeners :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    public void start ( ) {  
     
      this.m_timer.scheduleAtFixedRate( new TimerTask( ) {
     
        public void run ( ) {
     
            ...
            notifyUpdate( );
        }
     
      } , 0 , UPDATE_RATE);
     
    }
     
    private void notifyUpdate ( ) {  
     
      for (UpdateListener listener : this.m_listeners) {
     
          listener.clientUpdated( );
      }
    }
    Avec cette configuration, une exception de type ConcurrentModificationException est levée, de manière non systématique lors de la phase d'ajout des listeners.
    Cette exception pointe la boucle for de la méthode notifyUpdate.

    Solution testée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    private void notifyUpdate ( ) {  
     
      for (UpdateListener listener : new ArrayList<UpdateListener>(this.m_listeners)) {
     
          listener.clientUpdated( );
      }
    }
    Résultat :
    Je n'ai plus constaté d'exception.

    Problème 1 :
    Comme la méthode addUpdateListener est suceptible d'être appellée depuis un thread différent, je ne sais pas si il faut aussi faire attention à la synchronization (Collections.synchronizedList(), utilisation d'Iterator ...)

    Problème 2 :
    Etant donné que mon UPDATE_RATE est petit (20 ms), y a t'il un moyen moins couteux que de recréer une copie de la liste à chaque cycle ?

    Problème 3 :
    Est-ce que je ne devrais pas travailler du côté du AddListener plutôt que du côté de la méthode notifyUpdate ?
    Certe l'exception pointe vers cette méthode, mais j'ai lu que l'exception était dûe à la modification d'un liste alors qu'elle est en cours d'utilisation (de parcours?) et c'est plutôt dans le addListener que se produit la modification ...

    Merci pour vos remarques et vos propositions

  2. #2
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    Tu peux recuperer l'exception et retenter de l'ajout plusieurs fois

    Sinon, il y'a certainement un moyen de se reserver la collection dans l'execution de ton thread.

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Cette exception est levée lorsque tu utilises un itérateur et que malgré tout, tu tentes de changer la collection initiale.

    Ceci lèvera systématiquement une exception (oui, dans un même thread) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Collection a = new ArrayList();
    ... // remplissage de a.
     
    Iterator i = a.iterator();
    if (i.hasNext()) {
      Object o = iterator.next();
      a.add(...);
      // ou
      a.remove(...);
    }
    Pour résoudre le problème, il faut soit copier la collection, et utiliser l'itérateur de la copie (comme tu le fais), soit ne pas utiliser d'itérateur, et revenir aux indices. Enfin, dernière possibilité, si ceci gère une liste privée, utiliser exclusivement des méthodes synchronisées pour y accéder.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Février 2006
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 116
    Points : 128
    Points
    128
    Par défaut
    Salut,
    La copie est peut etre le plus simple. Sinon tu peux faire un buffer sur l'ajout, une liste temporaire synchronisée. Et dans le notify avant d'iterer tu vides le buffer pour les ajouter aux listeners. Cela permetr d'eviter un bloquage trop long si le notify dure.

Discussions similaires

  1. [EJB3] ConcurrentModificationException collection list multi-thread jboss
    Par gudepier42 dans le forum Java EE
    Réponses: 1
    Dernier message: 10/05/2010, 13h09
  2. [C#] Conseil sur l'utilisation de collection
    Par shinchan dans le forum Windows Forms
    Réponses: 5
    Dernier message: 23/03/2006, 11h02
  3. [Collection] ConcurrentModificationException
    Par calvin dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 19/05/2004, 09h00
  4. [web] Cherche un conseil pour un livre perl-tk
    Par Anonymous dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 29/04/2002, 15h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo