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

EDT/SwingWorker Java Discussion :

Synchroniser des SwingWorkers


Sujet :

EDT/SwingWorker Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut Synchroniser des SwingWorkers
    Bonjour,

    Je développe un modèle de simulation des courants marins.
    Je dispose d'un objet Simulation chargé de faire les calculs et d'une MainFrame (l'interface graphique) qui me permet de piloter la simulation et d'afficher le mouvement des courants.
    L'objet Simulation offre une méthode initSimu() et une méthode runSimu().
    La MainFrame contient :
    * bouton "Init" qui initialise la simulation (lecture d'un fichier configuration).
    * bouton "Run" qui lance son exécution.
    * un JPanel "panelSimu" où sont dessinés les courants marins.

    J'utilise un SwingWorker pour initialiser la simulation (appelons le sw_init) et un SwingWorker pour exécuter la simulation (appelons le sw_run).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    sw_init {
       @Override
       protected Object doInBackground() throws Exception {
          simulation.initSimu(); //lit les paramètres dans un fichier et initialise les variables de la simulation
          return null;
        }
     
        @Override
        protected void done() {
        // Affiche sur le JPanel le domaine géographique de la simulation
        panelSimu.repaint()
        }
    sw_run est fichu pareil sauf qu'il lance en background la procédure simulation.runSimu()

    Un click sur le bouton "Init" appelle sw_init.execute().
    Un click sur "Run" appelle sw_run.execute().

    Pour que le programme tourne bien, il ne faut pas que la méthode runSimu() s'exécute avant que initSimu() soit finie.

    Problèmes rencontrés à l'exécution : si je clique sur Init et j'attends que la tâche soit complètement exécutée avant de cliquer sur Run, il n'y a aucun problème. Si je clique sur Init et juste après sur Run, et bien la simu tente de tourner alors qu'elle n'a pas fini de s'initialiser et plante.

    Une solution facile, consiste à désactiver le bouton Run tant que l'initialisation n'est pas terminée. Mais je veux que l'utilisateur puisse cliquer successivement sur Init et Run, et que le programme gère la synchro des SwingWorkers.

    Ma question : Comment dois-je synchroniser mes deux SwingWorkers (je dis deux dans cet exemple, mais ma question vaut pour plusieurs SW) ? Je n'arrive pas à utiliser correctement wait() and notifyAll(), et le mot-clé Synchronized au sein des SwingWorkers.

    Le post est un peu long, pardon, mais je préfère donner toute l'information dès le début. D'avance merci pour vos éclaircissements.
    Philippe.

  2. #2
    Membre averti
    Inscrit en
    Février 2007
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 26
    Par défaut
    Et pourquoi tu ne ferais pas un 3ème bouton ''Do the work'' qui t'appelle successivement init et run ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut
    Bonjour Mischka,

    Merci pour ta suggestion.
    La configuration que je décris dans le premier message n'est là que pour illustrer mon problème. Je ne cherche pas de solutions alternatives.
    J'essaie de comprendre ce qui se passe quand on a plusieurs SwingWorkers dans une application, et comment synchroniser leurs actions.

  4. #4
    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,



    Pourquoi ne pas tout simplement attendre que le SwingWorker d'initialisation soit terminé au tout début du second SwingWorker :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	protected Object doInBackground() throws Exception {
    		sw_init.get(); // bloquera jusqu'à la fin du SwingWorker
     
    		// => Ton traitement ici
    	}
    a++

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut
    Bonjour adiGuba,

    Je ne suis pas encore suffisamment familier des SwingWorkers pour penser à appeler la méthode get() !! Merci beaucoup pour le coup de pouce

    J'ai essayé ... mais sans trop de succés. L'appel sw1.get() à l'interieur de sw2.doInBackGround(), comme tu le suggères, interrompt l'exécution du traitement de la tâche en background et le programme passe directement à la méthode sw2.done(). Il n'y a pas d'exception générée. Une idée du pourquoi ?
    J'observe exactement la même chose si je place un wait() en début de sw2.doInBackGround().

    J'ai essayé autre chose : j'appelle sw2.execute() depuis sw1.done(). Dans ce cas, les tâches sont parfaitement synchronisées. Mais cette solution ne répond pas exactement à mon problème. Le SwingWorker sw2 doit s'executer quand je clique sur un bouton, pas juste à la fin de sw1.

    Merci.

  6. #6
    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
    Citation Envoyé par pverley
    L'appel sw1.get() à l'interieur de sw2.doInBackGround(), comme tu le suggères, interrompt l'exécution du traitement de la tâche en background et le programme passe directement à la méthode sw2.done(). Il n'y a pas d'exception générée. Une idée du pourquoi ?
    J'observe exactement la même chose si je place un wait() en début de sw2.doInBackGround().
    Es-tu vraiment sûr de cela ? Fais attention car les exceptions remontées par doInBackground() ne sont pas affiché sur la console si tu ne le fais pas explicitement...

    a++

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

Discussions similaires

  1. jeu réseau: synchronisation des latences
    Par orelero dans le forum Développement
    Réponses: 2
    Dernier message: 19/04/2006, 11h32
  2. Question sur la synchronisation des threads.
    Par sebastieng dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 07/12/2005, 15h55
  3. synchroniser des actions
    Par Homer dans le forum Langage
    Réponses: 6
    Dernier message: 03/11/2005, 08h51
  4. [Synchronisation des processus] Problème du boulanger
    Par Giovanny Temgoua dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 26/02/2005, 12h40

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