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 :

swingworker multiple threads


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre régulier
    Homme Profil pro
    Dévelopeur Cobol + Java J2SE
    Inscrit en
    Novembre 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dévelopeur Cobol + Java J2SE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 72
    Points : 77
    Points
    77
    Par défaut swingworker multiple threads
    bonjour, pouvez vous me donner un exemple pour que traitement1() et traitement2() s’exécutent en parallèle (traitement2() peut commencer en même temps que traitement(1)). Je veux bien sûr que mon done() s'exécute quand trt1 et trt2 sont terminés.
    Merci !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    jframe.getJLabelEtoile().setText("X");
    new SwingWorker<Void, Void>() {
    	@Override
    	protected Void doInBackground() throws Exception {
    		traitement1();
    		traitement2();
    		return null;
    	}
    	protected void done() {
    		jframe.getJLabelEtoile().setText("");
    		jframe.repaint();
    	}
    }.execute();

  2. #2
    Membre éclairé
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Points : 844
    Points
    844
    Par défaut
    Bonjour,

    Pour moi le plus simple est de rendre traitement1 et traitement2 chacun un SwingWorker surtout si ils publient chacun des chunks vers l'edt pour le rafraîchissement des données.
    Il suffit ensuite de gérer la réunion des 2 traitements pour le done().
    Il faut faire attention car le done s'execute dans l'EDT, donc on ne peut pas faire un join() sur l'autre thread, ce qui aurait comme conséquence de bloquer l'EDT

    Tu pourrais faire quelque chose comme ceci:

    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    public class Exemple {
     
    	private AtomicInteger joiner = new AtomicInteger();
     
    	public static void main(String[] args) {
    		new Exemple().execute();
    	}
     
    	public void execute() {
    		joiner.set(0);
     
    		SwingWorker<Void,Void> first = new SwingWorker<Void, Void>() {
    			@Override
    			protected Void doInBackground() throws Exception {
    				traitement1();
    				return null;
    			}
    			protected void done() {
    				Exemple.this.done();
    			}
    		};
     
    		SwingWorker<Void,Void> second = new SwingWorker<Void, Void>() {
    			@Override
    			protected Void doInBackground() throws Exception {
    				traitement2();
    				return null;
    			}
    			protected void done() {
    				Exemple.this.done();
    			}
    		};
     
    		first.execute();
    		second.execute();
    		while( !first.isDone() || !second.isDone() ) {
    			try {
    				first.get();
    				second.get();
    			}
    			catch(Exception e) {
     
    			}
    		}
    		System.out.println("All is done, we can finish the main thread that will stop the app");
    	}
     
    	private void traitement1() {
    		System.out.println("Début traitement1");
    		try {
    			Thread.sleep(5000);
    		}
    		catch(InterruptedException e) {
     
    		}
    		System.out.println("Fin traitement1");
    	}
     
    	private void traitement2() {
    		System.out.println("Début traitement2");
    		try {
    			Thread.sleep(3000);
    		}
    		catch(InterruptedException e) {
     
    		}
    		System.out.println("Fin traitement2");
     
    	}
     
    	private void done() {
    		long value = joiner.incrementAndGet();
    		if( value == 2 ) {
    			doneImpl();
    		}
    	}
     
    	private void doneImpl() {
    		System.out.println("Done on EDT ? " + SwingUtilities.isEventDispatchThread() );
    	}
    }
    JBusyComponent, une API pour rendre occupé un composant swing.
    SCJP Java 6.0 (90% pass score)

  3. #3
    Membre régulier
    Homme Profil pro
    Dévelopeur Cobol + Java J2SE
    Inscrit en
    Novembre 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dévelopeur Cobol + Java J2SE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 72
    Points : 77
    Points
    77
    Par défaut
    Citation Envoyé par divxdede Voir le message
    Bonjour,

    Pour moi le plus simple est de rendre traitement1 et traitement2 chacun un SwingWorker surtout si ils publient chacun des chunks vers l'edt pour le rafraîchissement des données.
    Il suffit ensuite de gérer la réunion des 2 traitements pour le done().
    Il faut faire attention car le done s'execute dans l'EDT, donc on ne peut pas faire un join() sur l'autre thread, ce qui aurait comme conséquence de bloquer l'EDT

    Tu pourrais faire quelque chose comme ceci:

    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    public class Exemple {
     
    	private AtomicInteger joiner = new AtomicInteger();
     
    	public static void main(String[] args) {
    		new Exemple().execute();
    	}
     
    	public void execute() {
    		joiner.set(0);
     
    		SwingWorker<Void,Void> first = new SwingWorker<Void, Void>() {
    			@Override
    			protected Void doInBackground() throws Exception {
    				traitement1();
    				return null;
    			}
    			protected void done() {
    				Exemple.this.done();
    			}
    		};
     
    		SwingWorker<Void,Void> second = new SwingWorker<Void, Void>() {
    			@Override
    			protected Void doInBackground() throws Exception {
    				traitement2();
    				return null;
    			}
    			protected void done() {
    				Exemple.this.done();
    			}
    		};
     
    		first.execute();
    		second.execute();
    		while( !first.isDone() || !second.isDone() ) {
    			try {
    				first.get();
    				second.get();
    			}
    			catch(Exception e) {
     
    			}
    		}
    		System.out.println("All is done, we can finish the main thread that will stop the app");
    	}
     
    	private void traitement1() {
    		System.out.println("Début traitement1");
    		try {
    			Thread.sleep(5000);
    		}
    		catch(InterruptedException e) {
     
    		}
    		System.out.println("Fin traitement1");
    	}
     
    	private void traitement2() {
    		System.out.println("Début traitement2");
    		try {
    			Thread.sleep(3000);
    		}
    		catch(InterruptedException e) {
     
    		}
    		System.out.println("Fin traitement2");
     
    	}
     
    	private void done() {
    		long value = joiner.incrementAndGet();
    		if( value == 2 ) {
    			doneImpl();
    		}
    	}
     
    	private void doneImpl() {
    		System.out.println("Done on EDT ? " + SwingUtilities.isEventDispatchThread() );
    	}
    }
    Merci.
    Je ne suis pas sûr de tout comprendre. Je ne sais pas ce que c'est que des chunks. Pour l'instant mes traitements n'ont rien à produire vers l'edt il me semble. Je rafraichis mon écran dans le done() ligne 10/11 de mon code. Et la boucle while de ton code va s'éxécuter dans l'EDT et donc figer mon écran non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (!first.isDone() || !second.isDone()) {
        try {
            first.get();
            second.get();
        } catch (Exception e) {
     
        }
    }

  4. #4
    Membre éclairé
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Points : 844
    Points
    844
    Par défaut
    Les "chunks" sont des données que tu transmets à l'EDT via la méthode #publish() de ton SwingWorker et que tu traites via la méthode #process()
    - La méthode #publish() est donc appelée par le "business thread" de ton worker
    - La méthode #process() est appelée de l'EDT

    Cette mécanique permet de transmettre des états concernant le traitement en cours de réalisation et adapter ton interface graphique.


    Sinon concernant le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (!first.isDone() || !second.isDone()) {
        try {
            first.get();
            second.get();
        } catch (Exception e) {
     
        }
    }
    Ce n'est pas appelé de l'EDT mais du thread principal (celui qui exécute le main)
    Cette attente n'a pas beaucoup d’intérêt par rapport à ta question, il s'agissait surtout d'attendre avant de rendre la main.
    Car les workers (si je ne me trompe pas) créer des Thread de type "daemon". C'est à dire que si les seuls threads vivants qui subsistent sont des threads daemons, alors l'application s’arrête.
    Donc si j'avais laissé le thread principal se finir, l'application se serait arrêté avant de terminer les 2 traitements. Avec un environnement graphique initialisé, je n'aurais pas eu ce soucis.
    Dans ton cas, tu ne devrais pas avoir besoin de réaliser ce bout de code, surtout si dans ton cas tu lances tes workers de l'EDT, ca aurait effectivement comme conséquence de bloquer tout...

    Dans mon exemple, il y a 4 threads en jeu
    - le thread principal executant le main() et donc la méthode Exemple#execute()
    - le business thread du premier worker exécutant traitement1()
    - le business thread du second worker exécutant traitement2()
    - le thread de l'EDT exécutant le done()
    JBusyComponent, une API pour rendre occupé un composant swing.
    SCJP Java 6.0 (90% pass score)

  5. #5
    Membre régulier
    Homme Profil pro
    Dévelopeur Cobol + Java J2SE
    Inscrit en
    Novembre 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dévelopeur Cobol + Java J2SE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 72
    Points : 77
    Points
    77
    Par défaut
    Citation Envoyé par divxdede Voir le message
    Les "chunks" sont des données que tu transmets à l'EDT via la méthode #publish() de ton SwingWorker et que tu traites via la méthode #process()
    - La méthode #publish() est donc appelée par le "business thread" de ton worker
    - La méthode #process() est appelée de l'EDT

    Cette mécanique permet de transmettre des états concernant le traitement en cours de réalisation et adapter ton interface graphique.


    Sinon concernant le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (!first.isDone() || !second.isDone()) {
        try {
            first.get();
            second.get();
        } catch (Exception e) {
     
        }
    }
    Ce n'est pas appelé de l'EDT mais du thread principal (celui qui exécute le main)
    Cette attente n'a pas beaucoup d’intérêt par rapport à ta question, il s'agissait surtout d'attendre avant de rendre la main.
    Car les workers (si je ne me trompe pas) créer des Thread de type "daemon". C'est à dire que si les seuls threads vivants qui subsistent sont des threads daemons, alors l'application s’arrête.
    Donc si j'avais laissé le thread principal se finir, l'application se serait arrêté avant de terminer les 2 traitements. Avec un environnement graphique initialisé, je n'aurais pas eu ce soucis.
    Dans ton cas, tu ne devrais pas avoir besoin de réaliser ce bout de code, surtout si dans ton cas tu lances tes workers de l'EDT, ca aurait effectivement comme conséquence de bloquer tout...

    Dans mon exemple, il y a 4 threads en jeu
    - le thread principal executant le main() et donc la méthode Exemple#execute()
    - le business thread du premier worker exécutant traitement1()
    - le business thread du second worker exécutant traitement2()
    - le thread de l'EDT exécutant le done()
    ok merci !

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 09/06/2014, 10h49
  2. Gestion de multiples Threads
    Par ptitmanuk dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 12/11/2011, 02h13
  3. SwingWorker ,SwingUtilities & threads
    Par you98 dans le forum EDT/SwingWorker
    Réponses: 3
    Dernier message: 01/10/2010, 18h50
  4. Multiple thread peuvent ils bloquer (EDT) malgre invokeLater
    Par murgen23 dans le forum EDT/SwingWorker
    Réponses: 3
    Dernier message: 12/09/2008, 08h56
  5. Multiples threads vb.net
    Par tlibert dans le forum VB.NET
    Réponses: 9
    Dernier message: 27/02/2007, 14h14

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