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 :

Pb de Thread ?


Sujet :

Java

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut Pb de Thread ?
    Bonjour,

    J'ai une application qui se charge de lire un fichier et ensuite, de ventiler chaque ligne du fichier dans un Thread de traitement en fonction d'un code enregistrement.

    fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    00001data
    00002data
    00001data
    00002data
    00001data
    00002data
    00001data
    00002data
    00001data
    00002data
    Mon programme principal boucle donc sur le fichier.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // Lire le fichier jusqu'à la fin
    while(!EOF) {
        ligne = lireLigneDuFichier();
        // Récup le code de la ligne
        code = ligne.substring(0, 5);
        // Si le code n'existe pas, on crée un nouveau traitement (Thread) pour ce code
        si (Hashtable.containtKey(code)) {
            Hashtable.put(code, new Traitement());
        }
        // On demande au traitement de traiter la ligne lue
        ((Traitement)Hashtable.get(code)).proceed(ligne);
    }
    Voici le code de ma classe Traitement :
    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
    public class Traitement extends Thread {
    	private Ihm ihm;
     
    	private String id;
     
    	private int nbLigne;
     
    	Lot(Ihm ihm, String lot) {
    		super();
    		this.ihm = ihm;
    		this.id = lot;
    		this.start();
    	}
     
    	public void run() {
    		nbLigne = 0;
    	}
     
    	public void proceed(String ligne) {
    		nbLigne++;
    		ihm.writeln(id + ": [START] " + nbLigne);
    		try {
    			Thread.sleep(500);
    			ihm.writeln(id + ": [STOP] " + nbLigne);
    		} catch(Exception ex) {
    			ihm.writeln(ex.toString());
    		}
    	}
    }
    Et voici le résultat lorsque je lance mon traitement...
    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
     
    [29/12/2009 17:23:15] [START]
    [29/12/2009 17:23:15] [INFO] Lot : 00001            
    [29/12/2009 17:23:15] 00001            : [START] 1
    [29/12/2009 17:23:16] 00001            : [STOP] 0
    [29/12/2009 17:23:16] [INFO] Lot : 00002            
    [29/12/2009 17:23:16] 00002            : [START] 1
    [29/12/2009 17:23:16] 00002            : [STOP] 0
    [29/12/2009 17:23:16] 00001            : [START] 1
    [29/12/2009 17:23:17] 00001            : [STOP] 1
    [29/12/2009 17:23:17] 00002            : [START] 1
    [29/12/2009 17:23:17] 00002            : [STOP] 1
    [29/12/2009 17:23:17] 00001            : [START] 2
    [29/12/2009 17:23:18] 00001            : [STOP] 2
    [29/12/2009 17:23:18] 00002            : [START] 2
    [29/12/2009 17:23:18] 00002            : [STOP] 2
    [29/12/2009 17:23:18] 00001            : [START] 3
    [29/12/2009 17:23:19] 00001            : [STOP] 3
    [29/12/2009 17:23:19] 00002            : [START] 3
    [29/12/2009 17:23:19] 00002            : [STOP] 3
    [29/12/2009 17:23:19] 00001            : [START] 4
    [29/12/2009 17:23:20] 00001            : [STOP] 4
    [29/12/2009 17:23:20] 00002            : [START] 4
    [29/12/2009 17:23:20] 00002            : [STOP] 4
    [29/12/2009 17:23:20] [STOP]
    J'ai normalement 5 enregistrements pour chaque lot, mais mon compteur d'enregistrement associé à chaque Traitement ne s'incrémente pas bien et je ne comprend pas pourquoi.

  2. #2
    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
    ta méthode proceed est appelée et traitée par ton thread courant, tandis que ta méthode run() est faite par ton thread de traitement. Résultat, tu incrément nbligne dans proceed (Thread main) alors que, en parallèle, tu as Traitement qui passe dans run() et remet nbligne à 0. En fait, a part mettre nbligne à 0, te thread ne font absolument rien!

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut
    Oula, j'étais vraiment pas en forme hier quand j'ai écris ma classe Lot...

    Donc en effet, il n'y a aucune chance que cela fonctionne comme je le souhaite en écrivant ma classe comme cela.
    Par contre, maintenant que j'ai les yeux en face des trous, je ne vois pas trop comment m'en sortir pour démarrer mes Threads (Lot) puis les mettre en attente de données à traiter (ni comment leur passer les données).

    J'ai bien pensé à qqch comme le code ci-dessous, mais comme ca serait trop simple et bien ca ne fonctionne pas...
    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
    package com.bigben.casa;
     
    public class Lot extends Thread {
    	private Ihm ihm;
     
    	private String id;
    	private String ligne;
     
    	private int nbLigne;
    	private boolean end;
     
    	Lot(Ihm ihm, String lot) {
    		super();
    		this.ihm = ihm;
    		this.id = lot;
    		nbLigne = 0;
    		this.start();
    	}
     
    	public void run() {
    		while(!end) {
    		// Traitement de ligne
                    }
    	}
     
    	public void proceed(String ligne) {
    		this.ligne = ligne;
    	}
     
    	public void end() {
    		end = true;
    	}
    }
    ligne deviendra un Vecteur de lignes pour que mon programme principal puisse soumettre des lignes sans se soucier de savoir si le traitement de la précédente est terminé.
    La méthode end() est appelée par mon programme principal lorsque ce dernier a terminé de lire le fichier.

  4. #4
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Le code de la lecture du fichier ne m'inspire guère. Je serais curieux de voir ce qui se cache derrière tout cela.


    Sinon pour en revenir aux threads : que veux-tu faire avec exactement ? Quel est le traitement ?


    a++

  5. #5
    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
    Pourquoi ne pas utiliser une blockingQueue pour transmettre les lignre à traiter? Le thread n'aurais qu'a suivre la queue ligne par ligne. Et ton main remplirait simplement les queues au fur et à mesure de la lecture.

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut
    Je ne vois pas pourquoi ma lecture de fichier ne te plait pas ?
    Il s'agit d'une simple boucle "tant que". Tant que la fin du fichier n'a pas été atteinte, lire une ligne du fichier et la traiter.

    Sinon, concernant le traitement que je souhaite mettre en place. Je vais essayer de donner plus d'explications.
    J'ai un fichier qui contient des données de plusieurs lots et chaque lot doit être considéré comme un ensemble indépendant. Pour chaque ligne du fichier, je peux identifier le lot auquel elle appartient à partir d'un code qui compose cette ligne.

    Donc mon idée est de lire le fichier et ensuite, de repartir chaque ligne en fonction du lot auquel elle appartient.

    Voici un exemple de fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    BIB1_livre1
    BIB1_livre2
    BIB2_livre1
    BIB2_livre2
    BIB2_livre3
    BIB3_livre1
    BIB1_livre2
    BIB3_livre2
    Donc mon programme principal se charge de lire le fichier et d'identifier à quelle bibliothèque appartient le livre à partir du code bibliothèque (BIB1, BIB2, BIB3). Ensuite, je voudrais qu'il répartisse chaque livre dans un programme de traitement de bibliothèque qui correspond au code bibliothèque du livre.

    Class Flux
    => Hashtable de bibliothèque (à chaque code bibliothèque trouvé, on crée une nouvelle Bibliothèque dans la table dont le rôle sera de traiter les livres qui lui seront affectés)

    Class Bibliothèque
    => Thread indépendant, démarré par la classe Flux lorsque cette dernière identifie une nouvelle Bibliothèque.

    Une fois démarrée, j'aimerais que ma classe Bibliothèque se mette en attente d'informations (livres) de la part de ma classe Flux en charge de lire mon fichier.
    Ma classe doit attendre et traiter les données transmises par ma classe Flux jusqu'à ce que cette dernière lui envoie un message d'arrêt (fin de fichier)

    J'espère avoir été plus clair avec ces explications.

  7. #7
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bigben99 Voir le message
    Je ne vois pas pourquoi ma lecture de fichier ne te plait pas ?
    Il s'agit d'une simple boucle "tant que". Tant que la fin du fichier n'a pas été atteinte, lire une ligne du fichier et la traiter.
    C'est justement le while(!EOF) qui me semble bizarre... mais il faudrait un code plus détaillé en fait.



    Citation Envoyé par bigben99 Voir le message
    Ma classe doit attendre et traiter les données transmises par ma classe Flux jusqu'à ce que cette dernière lui envoie un message d'arrêt (fin de fichier)
    Pourquoi en faire un traitement multithreadé ???

    a++

  8. #8
    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
    l'utilisation de threads pour ta bibliothèque ne se justifie que si les traitements liès à l'ajout d'éléments sont lourd, ca permet de profiter en parallèle du SPU (traitement lourd) et des IOs (lecture de fichier).

  9. #9
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut
    Ok, pour le EOF, c'est une façon de parler car ma boucle while est un peu plus compliquée qu'une simple boucle de lecture. Mais la lecture du flux ne me pose pas de problème. Donc j'ai simplifié en disant que je lisais le fichier ligne à ligne jusqu'à la fin (EOF).

    Citation Envoyé par adiGuba Voir le message
    Pourquoi en faire un traitement multithreadé ???
    Car le traitement des "livres" est lourd, les données qui sont transmises à chaque "bibliothèque" peuvent nécessiter un traitement assez long donc je ne voudrais pas que le traitement d'un livre pénalise l'ensemble des "bibliothèques".

    Je peux avoir par exemple une "bibliothèque" avec 200 000 "livres" et une autre avec 200 "livres". Comme les livres sont répartis de façon aléatoire dans mon flux, je ne voudrais pas que la "bibliothèque" de 200 "livres" soit obligée d'attendre que la "bibliothèque" de 200 000 livres ai fini de traiter ses livres sous prétexte que le 200ème "livre" est le dernier du fichier.

  10. #10
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    C'est quoi comme traitement ? Et sur combien de processeur ton application va tourner ?

    Car si tu n'as qu'un seul processeur et que tu as de vrais traitements lourds cela risque de ne pas changer grand chose voir d'empirer la situation (à cause de la synchronisation).


    Avec des sleep() ca marche peut-être car tu endors les threads, mais si tu fais 200 threads qui bouffe du CPU ca risque de ne rien changer voir d'empirer les choses en retardant tous les résultats



    Donc déjà il faudrait limiter les threads au nombre de processeurs. Ensuite il serait surement utile de passer par les Executors pour ne pas manipuler directement les threads...


    a++

  11. #11
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 120
    Points
    120
    Par défaut
    Merci pour vos réponses, dans un premier temps, je vais voir les résultats produits sans multi-thread.
    Il n'y a qu'un seul processeur sur la machine qui fera tourner le programme mais mon objectif de faire tourner mon traitement en multi-thread n'était pas de gagner du temps sur chaque bibliothèque, mais de laisser une chance à une petite bibliothèque de voir son traitement terminé avec une autre bien plus grosse.

    Comme je l'ai dit plus haut, je peux parfaitement avoir 1 livre de la bibliothèque BIB1 en premier dans le fichier, puis 200.000 de la seconde bibliothèque (BIB2) puis le 2ème et dernier livre de BIB1 en dernier enregistrement du fichier.
    Si je ne fais pas de multi-thread, BIB1 n'a aucune chance de se terminer rapidement...

  12. #12
    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
    dans ce cas, puisque je suppose que tu lit le fichier dans l'ordre, tu peux très bien lire tout le fichier, trier par ordre de bibliothèque croissante et traiter les bibliothèques les plus rapides en premier

    Si tu met un thread par bibliothèque, soit conscient du fait que tu ne pourra pas traiter 10.000 bibliothèques en //, au delà d'une 50aine, tu risque de voir le système s'effondrer.

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28
  3. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/2002, 13h53
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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