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 :

[ConcurrentModificationException] Arraylist et Timer


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Par défaut [ConcurrentModificationException] Arraylist et Timer
    Salut tous,

    j'ai droit à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    java.util.ConcurrentModificationException
            at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:448)
            at java.util.AbstractList$Itr.next(AbstractList.java:419)
    quand je parcourt un ArrayList depuis un timer ...
    La question est donc : existe t'il un type de liste qui supporte le parcourt en parallèle par plusieurs processus ? ou un moyen de parcourir un Arraylist qui ne lèverait pas cette exception ?

    Merci

    Question subsidiaire : mais pourquoi diantre n'y a t'il pas une méthode setValue(int value) dans la classe Integer ???

  2. #2
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Bonjour,

    1°) oui il faut chercher les liste dites "ThreadSafe" on en a parler y a pas longtemps sur ce forum (a vrai dire ca reviens souvent) ou sur java.sun.com

    2°) parce qu'il y a deja l'operateur d'affectation =. Cette reponse est bete mais je comprend pas bien la question subsidiaire

  3. #3
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Citation Envoyé par BainE
    Bonjour,

    1°) oui il faut chercher les liste dites "ThreadSafe" on en a parler y a pas longtemps sur ce forum (a vrai dire ca reviens souvent) ou sur le site java de sun

    2°) parce qu'il y a deja l'operateur d'affectation =. Cette reponse est bete mais je comprend pas bien la question subsidiaire
    dsl j ai fait citer au lieu de editer
    d'accord c'est bon

  4. #4
    Membre confirmé Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Par défaut
    pour la question subsidiaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Integer theInteger1 = new Integer(1);
    Integer theInteger2 =  theInteger1;
    // comment faire pour changer la valeur à la fois dans theInteger1  et theInteger2 ???
     
    theInteger2 = new Integer(2);
    // theInteger1 continue de valoir 1 (enfin il me semble)
    j'ai du faire ma propre classe Integer avec une méthode setValue ...

    Je reviendrais sur le sujet d'origine demain la je suis fatigué

  5. #5
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut Re: [ConcurrentModificationException] Arraylist et Timer
    Salut,

    Citation Envoyé par lebesnec
    La question est donc : existe t'il un type de liste qui supporte le parcourt en parallèle par plusieurs processus ? ou un moyen de parcourir un Arraylist qui ne lèverait pas cette exception ?
    Le problème ne vient pas du parcours mais de modification de la liste pendant le parcours...


    Cela peut survenir si tu utilises la List dans différents threads, et dans ce cas il faut utiliser une liste synchronisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List list = Collections.synchronizedList(new ArrayList());
    Attention toutefois car l'utilisation des iterator il faut utiliser un bloc synchronized de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    synchronized(list) {
    	Iterator i = list.iterator();
    	while (i.hasNext()) {
    		i.next();
    	}
    }
    Le même principe existe pour les autres type de collections, et la classe Collections comporte un grand nombre de méthode utile




    Citation Envoyé par lebesnec
    Question subsidiaire : mais pourquoi diantre n'y a t'il pas une méthode setValue(int value) dans la classe Integer ???
    C'est une des philosophies de Java : l'utilisation de classes immuables...

    Une classe immuable est une classe qui ne change jamais de "valeur". Cela permet de simplifier un peu la gestion des objets.

    Cela permet d'éviter les constructeurs par copie lorsqu'on passe un objet en paramètre, où la définition de méthode "const" et l'utilisation de référence lorsqu'on passe un objet à une méthode...

    a++

  6. #6
    Membre confirmé Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Par défaut
    wow :o

    merci pour les infos je devrait arriver à me débrouiller maintenant

  7. #7
    Membre confirmé Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Par défaut
    bon je me suis peut être emballé quand j'ai dit que j'arriverai à me débrouiller

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    public class Poufpouf extends TimerTask implements Serializable {
     
        private transient Timer timer;
     
        private List sorties;
     
        public Poufpouf() {
            super();
            this.sorties = Collections.synchronizedList(new ArrayList());
     
            // pour que le timer appelle run() à intervalle fixe :
            date = new Date(System.currentTimeMillis());
            timer = new Timer(true);
            timer.schedule(this, date, 5);
        }
     
     
        /**
         * Cette méthode est apellée à intervalle régulier par le timer.
         */
        public void run() {
            synchronized (sorties) {
                for (Iterator i = sorties.iterator(); i.hasNext();) {
                    Plouf plouf = (Plouf) i.next();
                    plouf.hop();
                }
            }
        }
     
        public int getNbSorties() {
            synchronized (sorties) {
                return sorties.size();
            }
        }
     
        public void addSortie(Plouf plouf) {
              synchronized(sorties) {
                   sorties.add(plouf); 
              }
        }
     
        public void addEntrée() { 
            synchronized (sorties) {
                for (Iterator i = sorties.iterator(); i.hasNext();) {
                    Plouf plouf = (Plouf) i.next();           
                    plouf.addEntrée();
                }
            }
        }
     
        /**
         * support de la deserialization
         */
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            synchronized (sorties) {
                // on deserialise les champs non transient :
                in.defaultReadObject();
            }
     
            timer = new Timer(true);
            date = new Date(System.currentTimeMillis());
     
            timer.schedule(this, date, 5);
        }
     
    }
    et quand je lance tout le fourbis au dessus j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    java.util.ConcurrentModificationException
            at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:448)
            at java.util.AbstractList$Itr.next(AbstractList.java:419)
    sur le i.next() de la méthode run() ...

    help :

    merci

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 151
    Par défaut
    c'est comme a dit adiGuba tu modifiies ta liste pendant que tu itères

    es-tu sur à 100% que pendant que tu parcoures ta liste tu ne la modifie pas ? que ce soit dans ce thread ou un autre ?

    par exemple es-tu certain que ta méthode addSortie(Plouf plouf) n'est pas executée pendant que tu itères? ( mets toujours les messages pour tracer ). T uas mis des blocs synchronized mais peut etre que leproblème vient de là et que tu devrais revoir le problème d'exclusion mutuelle

    Et si tu modifies ta liste pendant que tu itères dessus alors il faut corriger ce problème d'exclusion mutuelle.

  9. #9
    Membre confirmé Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Par défaut
    effectivement il est possible que addSortie(Plouf plouf) soit appelée pendant que la méthode run() est en train de parcourir la liste. Mais dans ce cas là le bloc synchronized ne devrait pas empêcher la modification pendant l'itération ??? Je veut dire : le bloc synchronized sert bien à empècher 2 objets d'accèder à la liste en même temps ?

    sinon comment corriger ce "problème d'exclusion mutuelle" ??

    merci pour l'aide

  10. #10
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Tu n'as besoin d'utiliser le bloc synchronized que lors de l'utilisation de l'itérateur, mais pas sur les autres méthodes car c'est déjà gérer par synchronizedList(), par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public int getNbSorties() {
                return sorties.size();
        }
    Ensuite dans ta méthode run() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        public void run() {
            synchronized (sorties) {
                for (Iterator i = sorties.iterator(); i.hasNext();) {
                    Plouf plouf = (Plouf) i.next();
                    plouf.hop();
                }
            }
        }
    A quoi correspond plouf.hop() ? Est-ce que cette méthode peut modifier la liste sorties ???


    Citation Envoyé par lebesnec
    Mais dans ce cas là le bloc synchronized ne devrait pas empêcher la modification pendant l'itération ??? Je veut dire : le bloc synchronized sert bien à empècher 2 objets d'accèder à la liste en même temps ?
    Non il sert à empêcher deux Threads d'accéder à la liste en même temps. Donc si depuis ta méthode hop() tu modifies ta liste, tu aura une ConcurrentModificationException même si tu es dans le même Thread (lors d'un parcours avec un itérateur, on ne peut modifier la liste que via la méthode remove() de ce dernier...


    a++

  11. #11
    Membre confirmé Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Par défaut
    wow merci pour les infos.

    Je n'ai pas mon code source sous les yeux aujourd'hui, je regarderais ça ce weekend et je pourrais vous donner des info complémentaires lundi.


    @+

  12. #12
    Membre confirmé Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Par défaut
    (3 semaine plus tard )

    re-salut tous,

    la liste "sorties" n'est modifié que dans cette classe, donc a priori ça ne vient pas de là ...
    Par contre les objets contenu dans cette liste sont modifiés ailleurs, et je me demandait : comme la liste est synchronisé, est ce que les objets contenu dedans le sont aussi (et donc est ce que mon problème viendrait de là) ??

    merci :o

  13. #13
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 95
    Par défaut Dans le même ordre d'idée
    Bonjour,
    Tout d'abord, bonne année!!!

    J'ai bien lu les pistes données dans les réponses à lebesnec, mais j'avoue ne pas y voir plus clair. J'ai moi aussi cette fameuse ConcurrentModificationException alors que je croyais m'en sortir avec des listes synchronisées dans une méthode JUnit.

    Si vous avez des pistes, je suis preneur.
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    private List<P053Projection> retournerListeBeansFusionnes(List<P053Projection> liste1ToutesValeurs)
        {
            List<P053Projection> liste2 = Collections.synchronizedList(new ArrayList<P053Projection>());
            synchronized (liste2)
            {
                for (P053Projection P053Projection : liste1ToutesValeurs)
                {
                    if (P053Projection.getCOuB().compareTo("C") == 0)
                    {
                        liste2.add(P053Projection);
                    }
                    else
                    {
                        if (liste2.size() != 0)
                        {
                            Iterator iter = liste2.iterator();
                            while (iter.hasNext())
                            {
                                P053Projection P053Projection2 = (P053Projection) iter.next();
                                if (P053Projection.getCodi().compareTo(P053Projection2.getCodi()) == 0
                                    && P053Projection.getCodeA().compareTo(P053Projection2.getCodeA()) == 0
                                    && P053Projection.getCodeOpe().compareTo(P053Projection2.getCodeOpe()) == 0)
                                {
                                    P053Projection2.setCOuB(" ");
                                    Integer nbOperationsCumule = P053Projection.getNbOperations() + P053Projection2.getNbOperations();
                                    BigDecimal montantsCumule = P053Projection.getCumulMontants().add(P053Projection2.getCumulMontants());
                                    P053Projection2.setNbOperations(nbOperationsCumule);
                                    P053Projection2.setCumulMontants(montantsCumule);
                                    liste2.add(P053Projection2);
                                }
                                else
                                {
                                    liste2.add(P053Projection);
                                }
     
                            }
                        }
                    }
                }
            }
            return liste2;
        }
    D'avance, merci pour vos pistes.
    Thomas

  14. #14
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Ce n'est pas un problème de synchronisation puisque tu n'a qu'un seul thread. De plus ton objet "liste2" est créé à l'intérieur de la méthode et elle ne peut donc pas être partagé en dehors...

    Bref la synchronisation est tout bonnement inutile dans ce cas précis !


    Lorsque tu parcours une liste tu ne peux pas la modifier directement, à moins de passer par les méthodes de l'Iterator. Dans ton cas il faudrait peut-être passer par un ListIterator (plus complet).


    Maintenant je ne comprend pas trop l'algo...


    a++

    PS : il faudrait aussi faire gaffe au nommage... C'est illisible :/

  15. #15
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 95
    Par défaut
    Bonjour,

    Merci à toi pour ces réponses...mais je n'ai pas saisi le rôle de ListIterator dans l'affaire.

    Je vais me plonger dans la doc pour y voir plus clair.
    Encore merci.
    Thomas

Discussions similaires

  1. Exception "ConcurrentModificationException" et les ArrayList
    Par allouchi dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 19/03/2012, 19h51
  2. ArrayList meilleur algo parcours + ConcurrentModificationException
    Par gerudo dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 13/05/2009, 17h10
  3. [] [Réseau] Anti-timer, anti-idle
    Par clonevince dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 15/01/2003, 22h19
  4. Timer de précision
    Par guigui dans le forum MFC
    Réponses: 1
    Dernier message: 04/12/2002, 15h21
  5. Timer en µsecondes
    Par Dagobert dans le forum x86 16-bits
    Réponses: 3
    Dernier message: 25/11/2002, 00h59

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