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

Java Discussion :

[threads] Problème d'accès concurrent à une liste


Sujet :

Java

  1. #1
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    3 995
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 995
    Points : 2 528
    Points
    2 528
    Par défaut [threads] Problème d'accès concurrent à une liste
    Bonjour,

    J'ai un souci bizarre dans un traitement multithreadé. J'obtiens une exception java.util.ConcurrentModificationException quand je le lance plusieurs fois, alors qu'en principe, j'instancie la liste incriminée pour chaque nouveau thread :

    Le traitement est lancé à partir d'une servlet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      ...
      List<String> list = new ArrayList<String>();
      for (OrderPrint op : oi.getPrints()) {
        ...
        list.add(fileO.toString());
        ...
      }
      ...
    }
    Transmitter transmitter= new Transmitter(order,list);
    Mon constructeur dans la classe Transmitter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    protected List<String> files;
    protected Thread _thread;
     
    public Transmitter(Order order, List<String> files) {
      ...
      this.files = files;
      ...
      _thread = new Thread(this);
      _thread.start();
    }
    et mon run() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void run() {
      for (String file : files) { // ligne 99
        ...
      }
      ...
    }
    L'exception est levée sur le for de ma méthode run(), quand il accède à la liste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    java.util.ConcurrentModificationException
      at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
      at java.util.AbstractList$Itr.next(AbstractList.java:343)
      at com.pixvisio.icontact.print.cewecolor.transfer.Transmitter.run(Transmitter.java:99)
      at java.lang.Thread.run(Thread.java:619)
    Comme je l'indiquais plus haut, le traitement est lancé à partir d'une servlet, et l'erreur se produit si je relance cette servlet plusieurs fois.

    Configuration :
    -Java 6 update 7
    -serveur Resin Pro 3.1.6
    -système Debian Linux, kernel 2.6.18

    Quelqu'un a une idée de qui se passe ?

  2. #2
    Membre expert
    Avatar de Gueritarish
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2007
    Messages
    1 800
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 800
    Points : 3 919
    Points
    3 919
    Par défaut
    Salut,

    L'exception référence la ligne 99 parce que l'exception est levé au passage dans ta boucle. Pour ma part, je pense que tu modifies la liste files dans la boucle foreach incluse dans le run.
    Si possible, tu peux nous donner le code source de cette méthode?

    Voilà, à+
    Gueritarish
    Pas de questions technique par MP, les forums sont là pour ça.

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    3 995
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 995
    Points : 2 528
    Points
    2 528
    Par défaut
    J'en mets un peu plus, mais je ne modifie pas la liste dans la boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void run() {
      ...
      for (String file : files) { // ligne 99
        fis = new FileInputStream(destPath+file);
        ok=ftp.storeFile(file,fis);
        fis.close();
      }
      ...
    }
    En fait, à part un logger (Log4J) un peu au-dessus de la boucle, je n'accède pas à la liste ailleurs dans le run().
    Sinon, comme certains l'auront remarqué, la boucle transfert des fichiers par FTP en utilisant Apache Commons Net 1.4.1

    De plus, quand je ne lance le traitement qu'une seule fois, ça se passe très bien (d'ailleurs, le code est en production). Ce n'est que quand on lance plusieurs fois la servlet, ce qui lance plusieurs threads (mais devrait en principe instancier une nouvelle liste pour chaque thread) que l'erreur se produit.

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    est-ce que tu fais quelquechose avec ta liste après l'appel à new Transmitter ?

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    3 995
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 995
    Points : 2 528
    Points
    2 528
    Par défaut
    Non plus. C'est la fin du traitement en fait. En amont, je prépare les données (un certain nombre de fichiers jpeg, un zip et un fichier texte ) et ensuite, là, je transfère sur le serveur distant. Comme le transfert peut être long, je le fais dans un thread séparé pour pouvoir rendre la main. Le traitement dit juste "ok" au client, après ça, c'est tout.

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    3 995
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 995
    Points : 2 528
    Points
    2 528
    Par défaut
    C'est bon, j'ai trouvé. C'est une erreur de copier-coller : je lançais le transmitter depuis l'intérieur de la boucle, donc pendant que j'insérais les données dans la liste. Désolé pour la gène occasionnée...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Thread - Accès concurrent à une List
    Par paladice dans le forum Concurrence et multi-thread
    Réponses: 4
    Dernier message: 25/05/2015, 11h55
  2. Réponses: 9
    Dernier message: 15/02/2006, 20h54
  3. [ACCESS97] Problème d'accès concurrent
    Par mpascolo dans le forum Access
    Réponses: 2
    Dernier message: 08/11/2005, 10h31
  4. accés concurrent à une table
    Par shout dans le forum Oracle
    Réponses: 5
    Dernier message: 06/10/2005, 10h54
  5. Réponses: 4
    Dernier message: 16/06/2005, 15h37

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