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

Concurrence et multi-thread Java Discussion :

Implémentation d'un Thread


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut Implémentation d'un Thread
    Bonjour à tous,
    J'ai une petite question concernant les Thread. Je souhaite consulter un champ dans une base de données, cependant, pour l'instant, cela me fige toute mon interface graphique (en SWING). Je souhaite donc implémenter un Thread pour la recherche de mon champ dans la base de données (et en même temps afficher une fenêtre dans mon interface graphique qui affiche une animation montrant que la recherche dans la base de données est en cours).
    Voici ma question, est-ce que ce type d'architecture pourrait fonctionner ?

    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
     
    public class maFenetre extends JFrame implements ActionListener {
        ...
        public void actionPerformed(ActionEvent e) {
            ...
            // Si on clique sur un bouton
     
            // On récupère le nom d'une personne depuis un JTextField nommé "monChampTexte" de maFenetre
            String nom = monChampTexte.getText();
            // On lance une nouvelle fenêtre affichant l'animation
            FenetreDAttente f = new FenetreDAttente();
            // On fait la recherche dans la base de données à partir d'un nom
            int id = gestionnaire.rechercheID(nom);
            // On ferme la fenêtre d'attente
            f.dispose();
            // On affiche l'id dans un JLabel de maFenetre
            monLabel.setText(id);
            ...
        }
        ...
    }
    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
    
    public class Gestionnaire extends Runnable {
        // On déclare un attribut (résultat de la requête SQL)
        private int idClient = 0;
        ...
        public int rechercheID(String nom) {
            // On crée le thread
            Thread thread = new Thread(this);
            // On lance le thread
            thread.start();
    
            // A la fin de l'exécution du thread, est-ce qu'il rend la main ici ?
            // Ce qui m'arrangerait grandement pour renvoyer l'ID à maFenetre
    
            // On retourne l'idClient
            return idClient;
        }
    
        public void run() {
            // Tout le traitement de recherche dans la base de données
            // avec le retour du résultat qu'on enregistre dans idClient
            idClient = Integer.parseInt(resultatRequeteSql);
        }
        ...
    }
    Si cette architecture ne fonctionne pas, comment puis-je faire pour faire le traitement de la base de données en parallèle de l'affichage de maFenetre tout en renvoyant (depuis mon gestionnaire) à la fin l'idClient à maFenetre ?

    Merci d'avance pour vos réponses !

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Cela ne marchera pas car ta méthode rechercheID te rendra la main avant que le thread de recherche dans ta BD ne soit terminé.
    C'est plutôt à ton thread, donc dans la méthode run de mettre à jour ton JLabel en utilisant un SwingUtilities.invokeLater, car les composants graphiques doivent être mis à jour dans l'EDT (Event Dispatching Thread).

    Sinon, tu peux utiliser la classe SwingWorker présente dans l'api standard depuis Java 6, ou que l'on peut trouver sur le site de Sun pour les version précédentes.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    En effet, ça me paraissait trop simple. Le soucis, c'est que mon gestionnaire ne connaît en aucun cas maFenetre et donc mon JLabel.
    C'est pas joli de passer le JLabel au gestionnaire (et donc à mon modèle) juste pour l'afficher une fois dans ma vue.
    Sinon, je connais une autre méthode qui consisterait à utiliser une interface mais dans ce cas, c'est toute l'architecture de mon logiciel qui est à refaire, et je n'ai pas le temps...
    Vois-tu autre chose ?

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Disons que je ne vois pas les choses comme toi ou alors, je n'ai pas tout compris.
    Ton code SQL ne doit pas se trouver dans ta méthode run de ton thread.
    Il doit se trouver dans une autre classe appelée par ton thread, qui ensuite fera la mise à jour.
    Dans ce cas là, je ne vois rien de choquant à passer à ton thread une référence à la vue.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Voici mon architecture exacte :
    - la vue (maFenetre) envoie la recherche dans la base de données de l'idClient à partir de la classe Gestionnaire.
    - Le modèle (la classe Gestionnaire) lance un nouveau Thread (la méthode run() est donc dans la classe Gestionnaire).
    - Dans cette méthode run(), je fabrique la requête SQL à partir du nom du client et j'exécute une requête SQL en appelant (en effet) une méthode static se trouvant dans une autre classe (ConnexionBaseDeDonnees) qui elle renvoie l'idClient. L'idClient se trouve donc (à la fin de la méthode run() => après la requête SQL) dans la classe Gestionnaire.

    Ce que tu me proposes, si j'ai bien compris, ce serait de passer une référence de mon JLabel depuis ma vue à mon modèle par la méthode (rechercheID()) comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rechercheID(nom, monLabel);
    Puis d'enregistrer mon JLabel dans un attribut de ma classe Gestionnaire.
    Et enfin, de faire à la fin de ma méthode run() quelquechose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SwingUtilities.invokeLater(new Runnable() {
      monLabel.setText("Voici l'idClient : " + id) ;
    }) ;
    C'est bien ça ?

    Dans ce cas ok, mais quand est-ce que je pourrai déterminer dans ma vue (maFenetre) le moment où la requête SQL est terminée (donc quand le label a été mis à jour en affichant l'idClient) ? Puisque j'ai besoin de savoir quand exactement pour pouvoir fermer ma fenêtre qui affiche un message d'attente (avec l'animation) => f.dispose(); (voir dans le code plus haut)

    La solution serait peut être de passer une référence sur ma fenetre dans rechercheID() comme mon JLabel et fermer la fenêtre après la mise à jour de monLabel ?

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    En fait, je viens de me rendre compte que j'aimerais afficher la fenêtre d'attente dans un nouveau Thread, mais ce ne serait peut être pas une bonne utilisation des interfaces graphiques SWING.
    En gros, maFenetre (ma fenêtre principale) est gelée tant que le traitement dans la base de données n'est pas effectué. J'aimerais juste afficher une fenêtre d'attente avec un message ("Base de données en cours...") pendant que la fenêtre principale est gelée. Et puis fermer la fenêtre d'attente quand le traitement est fini.
    Comment puis-je lancer une fenêtre SWING dans un nouveau Thread Swing ?

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Je suis ok avec ton avant dernier poste.

    Ce n'est pas le lancement de ta fenêtre qui doit se faire dans un autre thread mais le traitement lourd.

    Tu peux regarder du côté de la JProgressBar ou du ProgressMonitor:
    http://java.sun.com/docs/books/tutor....html#monitors

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Ok, mais ce que je ne comprends pas, c'est que lorsque je lance une nouvelle fenêtre (fenêtre d'attente : JDialog modale) à partir de ma fenêtre principale, ça arrête le traitement de ma fenêtre principale (donc la recherche dans la BDD) tant que je n'ai pas fermé la fenêtre d'attente...

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Bizarre. Fais voir ton code.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Cela vient du fait que ma fenêtre d'attente est modale...
    En y réfléchissant, c'est logique...
    Tant pis, j'enlève la modalité...
    Tous mes soucis venait de là...

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Je pars sur ta première idée fr1man, merci pour tes réponses !

    EDIT : Juste pour info, ça marche très bien

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

Discussions similaires

  1. Evaluation de l'implémentation de mes threads
    Par Dudule70 dans le forum C#
    Réponses: 0
    Dernier message: 09/12/2014, 10h30
  2. Réponses: 2
    Dernier message: 27/07/2011, 15h23
  3. [THREAD] Implémentation d'une attente
    Par Ephasme dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 13/05/2008, 09h31
  4. [Threads] Implémenter une pile de processus
    Par Invité dans le forum Général Java
    Réponses: 7
    Dernier message: 30/07/2007, 12h14
  5. Réponses: 14
    Dernier message: 05/04/2007, 11h12

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