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 :

Problème avec la synchronization de 2 threads


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre du Club Avatar de Frac10
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Points : 43
    Points
    43
    Par défaut Problème avec la synchronisation de 2 threads
    Bonjour tout le monde !

    Bon alors le fait est que j'ai essayé de comprendre la synchronization via les tutoriels présents sur le site, mais il reste un petit problème pour mon application.

    L'application va dans un premier temps télécharger un fichier .xls sur le net et dans un deuxième temps l'ouvrir. Donc il faut que le premier thread soit terminé quand le deuxième commence...

    Donc j'ai essayé de mettre des synchronized, des wait() et des notify(), mais il reste toujours un problème.

    En effet, le thread qui télécharge le fichier utilise une classe à part qui affiche une barre de progression pour voir le temps que çà prend. Et le problème est que lorsque les threads sont synchronizés (de la mauvaise manière je pense), la barre de progression ne s'affiche plus et çà bloque la fenêtre. Alors que quand ils ne sont pas synchronizés, elle s'affiche et se rempli nickel.

    Je mets le code simplifié de l'application qui lance les 2 threads:
    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
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.*;
    import jxl.*;
     
    public class GetFile extends JFrame {
     
    	public GetFile() {
    		setSize(100, 100);
    		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    		setLocation((screen.width - this.getSize().width)/2,
    		 (screen.height - this.getSize().height)/2);
    		setContentPane(getJDesktopPane());
    		setVisible(true);
    	}
     
    	private JDesktopPane getJDesktopPane() {
    		JDesktopPane jdp = new JDesktopPane();
    		JPanel jp = new JPanel();
    		jp.setSize(100, 100);
    		jp.setLocation(new java.awt.Point(1,1));
     
    		JButton jb = new JButton("Go !");
     
    		jp.add(jb, BorderLayout.CENTER);
     
    		jb.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				go1();
    				go2();
    			}
    		});
     
    		jdp.add(jp);
    		jdp.setVisible(true);
    		jdp.updateUI();
     
    		return jdp;
    	}
     
    	synchronized private void go1() {
    		HTTPGetFile gf = new HTTPGetFile("http://otarie10.free.fr/datas.xls");
    		notify();
    	}
     
    	synchronized private void go2() {
    		try {
    			wait();
    			Workbook workbook = Workbook.getWorkbook(new File("datas.xls"));
    			Sheet sheet = workbook.getSheet(0);
     
    			workbook.close();
    		} catch (Exception e) {
    			System.out.println("Impossible d'ouvrir le fichier .xls");
    			System.out.println(e);
    		}
    	}
     
    	public static void main(String[] args) throws IOException {
    		JFrame.setDefaultLookAndFeelDecorated(true);
    		new GetFile();
    	}
    }
    La classe HTTPGetFile (récupérée sur un autre site) sert à télécharger le fichier passé en paramètre et à afficher la barre de progression.

    Voilà, je pense que çà vient du fait que je n'ai rien compris à la synchronization, mais si quelqu'un pouvait m'éclairer ce serait sympa...

    Merci d'avance !!!

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 11
    Points : 13
    Points
    13
    Par défaut
    Salut! Bon je ne pense pas être un pro de la synchro sous Java mais une chose est sûre j'ai gagné beacoup de temps de debug depuis que j'ai découvert la classe SwingWorker. C'est une classe utilitaire qui permet de gérer facilement les threads au sein d'une application Swing (librarie telechargeable ici). Cette classe fera d'ailleurs partie de javax dans Java SE 6.

    Je te conseille donc de faire usage de cette librairie pour toutes les actions lourdes qui pourraient figer ton interface.

    Voila plus bas un exemple d'usage pour le code que tu as envoyé. J'ai essayé de modifier un minimum ton code. J'ai remplacé tes fonctions "lourdes" par des sleep pour la demonstration.

    Pour revenir a ton probleme de base, je ne vois pas pourquoi tu veux faire deux threads dans la mesure ou la premiere dois terminer avant que la deuxieme puisse commencer ?! Une simple thread qui lance ton telechargement de XLS et puis l'ouverture du fichier devrait suffir. C'est ce que j'ai fait dans l'exemple plus bas.

    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
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
     
    import javax.swing.*;
     
    import org.jdesktop.swingworker.SwingWorker;
     
     
    public class GetFile extends JFrame {
     
    	private JButton jbGo;
     
    	private JTextArea jtaLog;
     
    	class LoadExcelTask extends SwingWorker<Void, Void> {
     
    		@Override
    		public Void doInBackground() {
    			go1();
    			go2();
    			return null;
    		}
     
     
    		@Override
    		public void done() {
    			jtaLog.append("Fini !\n");
    			jbGo.setEnabled(true);
    		}
    	}
     
    	public GetFile() {
    		setSize(300, 200);
    		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    		setLocation((screen.width - this.getSize().width) / 2,
    				(screen.height - this.getSize().height) / 2);
    		setContentPane(getJDesktopPane());
    		setVisible(true);
    	}
     
    	private JDesktopPane getJDesktopPane() {
    		final JDesktopPane jdp = new JDesktopPane();
    		JPanel jp = new JPanel();
    		jp.setSize(300, 200);
    		jp.setLocation(new java.awt.Point(1, 1));
    		jbGo = new JButton("Go !");
    		jp.add(jbGo, BorderLayout.CENTER);
     
    		jtaLog = new JTextArea(5, 20);
    		jtaLog.setMargin(new Insets(5, 5, 5, 5));
    		jtaLog.setEditable(false);
     
    		jp.add(new JScrollPane(jtaLog), BorderLayout.SOUTH);
    		jp.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
     
     
    		jbGo.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				jbGo.setEnabled(false);
    				new LoadExcelTask().execute();
    			}
    		});
    		jdp.add(jp);
    		jdp.setVisible(true);
    		jdp.updateUI();
    		return jdp;
    	}
     
    	private void go1() {
     
    		try {
    			jtaLog.append(String.format("Téléchargement du fichier XLS\n"));
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
     
    	private void go2() {
    		try {
    			jtaLog.append(String.format("Ouverture du fichier XLS\n"));
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
    	}
     
    	public static void main(String[] args) throws IOException {
    		JFrame.setDefaultLookAndFeelDecorated(true);
    		new GetFile();
    	}
    }
    Sinon en deux mots, le SwingWorker comment ca marche : tu implementes une classe de type SwingWorker. La methode doInBackground() doit etre implementée. C'est elle qui définie le travail lourd à effectuer. On peut optionellement implementer une methode done() qui sera lancée apres l'execution de doInBackground(). Il existe aussi des methode d'interruption etc... La classe est definie de maniere generique : deux types fournis en parametres mais dans ton cas ne t'en soucis pas et laisse <void, void> comme dans l'exemple.

    Voila j'espere que tout ca va t'aider...

    Bon code,
    lxegre

  3. #3
    Membre éclairé

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2002
    Messages
    346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 346
    Points : 737
    Points
    737
    Par défaut
    Il ne faut pas confondre, quand une methode est synchronized, celà ne veut pas dire qu'elle est synchronisé, mais celà veut dire qu'un seul thread peut passer dedans en même temps!

    Peut être que ton problème se situe donc au niveau de l'utilisation de méthode synchronized, en effet, si ce que tu veut c'est juste attendre que quelque chose soit fait avant de faire autre chose, alors le mot clé synchronized ne te sert à rien, un wait et un notify suffisent.

  4. #4
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par woodwai
    un wait et un notify suffisent.
    En faisant bien attention que le wait() ait lieu avant le notify()...
    (ou alors utiliser des sémaphores, c'est géré automatiquement le notify avant le wait (v avant le p))

  5. #5
    Membre du Club Avatar de Frac10
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Points : 43
    Points
    43
    Par défaut
    Tout d'abord, un grand merci à tous les 3 pour vous pencher sur mon problème !

    Ixegre, j'ai essayé avec le SwingWorker que tu m'as proposé, mais il lance les 2 threads ("go1" et "go2") à la suite sans attendre la fin du premier : je ne comprends pas pourquoi...

    Sinon pour woodwai et ®om, c'était bien une histoire de notify() et de wait(). Sauf que j'avais une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java.lang.IllegalMonitorStateException: current thread not owner


    Donc j'ai mis un synchronized devant les 2 notifyAll() et wait() et çà marche (par contre, je ne vois toujours pas pourquoi, mais bon faudra que je me penche sur ces histoires de threads un jour ou l'autre)...

    Voici le code :
    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
    82
    83
    84
    85
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.*;
    import jxl.*;
     
    public class GetFile extends JFrame {
     
    	private JButton jbGo;
     
    	public GetFile() {
    		setSize(100, 100);
    		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    		setLocation((screen.width - this.getSize().width)/2,
    		 (screen.height - this.getSize().height)/2);
    		setContentPane(getJDesktopPane());
    		setVisible(true);
    	}
     
    	private JDesktopPane getJDesktopPane() {
    		JDesktopPane jdp = new JDesktopPane();
    		JPanel jp = new JPanel();
    		jp.setSize(100, 100);
    		jp.setLocation(new java.awt.Point(1,1));
     
    		jbGo = new JButton("Go !");
     
    		jp.add(jbGo, BorderLayout.CENTER);
     
    		jbGo.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				jbGo.setEnabled(false);
    				lanceThread();
    			}
    		});
     
    		jdp.add(jp);
    		jdp.setVisible(true);
    		jdp.updateUI();
     
    		return jdp;
    	}
     
    	private void go1() {
    		HTTPGetFile gf = new HTTPGetFile("http://MonFichierXLS.xls");
    		synchronized (this) {
    			this.notifyAll();
    		}
    	}
     
    	private void go2() {
    		try {
    			synchronized (this) {
    				wait();
    			}
    			Workbook workbook = Workbook.getWorkbook(new File("datas.xls"));
    			Sheet sheet = workbook.getSheet(0);
     
    			workbook.close();
    			System.out.println("C'est bon !!!");
    		} catch (Exception e) {
    			System.out.println("Impossible d'ouvrir le fichier .xls");
    			System.out.println(e);
    		}
    	}
     
    	public void lanceThread() {
    		Thread t = new Thread() {
    			public void run() {
    				try {
    					go1();
    					go2();
    				} catch (Exception ex) {
    					System.out.println("erreur thread : " + ex);
    				}
    			}
    		};
    		t.start();
    	}
     
    	public static void main(String[] args) throws IOException {
    		JFrame.setDefaultLookAndFeelDecorated(true);
    		new GetFile();
    	}
    }
    Merci encore à tous !!!

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

    Citation Envoyé par Frac10
    Ixegre, j'ai essayé avec le SwingWorker que tu m'as proposé, mais il lance les 2 threads ("go1" et "go2") à la suite sans attendre la fin du premier : je ne comprends pas pourquoi...
    Parce que SwingWorker sert à cela !! Mais dans ton cas ce n'est pas un vraiment un problème de synchronisation : tes deux traitements sont simplement exécuter l'un à la suite de l'autre et tes notify()/wait() sont inutile :

    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
    	private void go1() {
    		HTTPGetFile gf = new HTTPGetFile("http://MonFichierXLS.xls");
    	}
     
    	private void go2() {
    		try {
    			Workbook workbook = Workbook.getWorkbook(new File("datas.xls"));
    			Sheet sheet = workbook.getSheet(0);
     
    			workbook.close();
    			System.out.println("C'est bon !!!");
    		} catch (Exception e) {
    			System.out.println("Impossible d'ouvrir le fichier .xls");
    			System.out.println(e);
    		}
    	}
    Citation Envoyé par Frac10
    Donc j'ai mis un synchronized devant les 2 notifyAll() et wait() et çà marche (par contre, je ne vois toujours pas pourquoi, mais bon faudra que je me penche sur ces histoires de threads un jour ou l'autre)...
    Parce que notify() et wait() permette des synchronisation entre différents thread, et qu'il doivent donc utiliser un verrou unique et donc des bloc synchronized... C'est indiqué dans la documentation de ces méthodes

    a++

  7. #7
    Membre du Club Avatar de Frac10
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Points : 43
    Points
    43
    Par défaut
    Ben merci bien pour ces explications adiGuba !
    Cà m'aide à mieux cerner la partie d'ombre que sont les threads...

  8. #8
    Membre du Club Avatar de Frac10
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Points : 43
    Points
    43
    Par défaut
    Heu désolé d'être aussi lourd, mais en fait le problème n'est pas résolu... Je pensais que çà fonctionnait et en fait pas du tout, çà se bloque après le 1ier processus.

    Je vais essayer d'être simple.
    J'ai 3 fichiers : le programme principal qui lance les 2 processus (un pour télécharger un fichier, l'autre pour le parcourir quand çà a fini de télécharger) et le programme pour télécharger le fichier qui lance un programme de gestion d'une barre de progression.

    Or au niveau du programme principal, si je mets mes 2 processus simplement à la suite, comme çà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    jbGo.addActionListener(new ActionListener() {
    	public void actionPerformed(ActionEvent e) {
    		jbGo.setEnabled(false);
    		go1();
    		go2();
    	}
    });
    ils se lancent l'un après l'autre (dans l'ordre) mais l'écran de la barre de progression ne s'affiche pas...

    J'ai donc mis dans le programme de téléchargement un thread pour lancer le programme de gestion de la barre de progression et cette fois-ci elle s'affiche correctement...
    ... Sauf que maintenant les 2 processus du programme principal ne se lancent plus dans l'ordre : le 2ième n'attend plus la fin du premier...

    Bref je ne comprends plus rien : est-ce un problème de threads ou pas ? Et si oui comment le résoudre ???

    Voici les 3 fichiers pour ceux qui voudraient tester :
    GetFile.java
    HTTPGetFile.java
    SplashScreen.java

    Merci d'avance !!!

  9. #9
    Membre confirmé Avatar de broumbroum
    Profil pro
    Inscrit en
    Août 2006
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 406
    Points : 465
    Points
    465
    Par défaut
    Je l'avais montré dans un autre "thread", ici tu peux faire une boucle autour du thread courant:

  10. #10
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par broumbroum
    Je l'avais montré dans un autre "thread", ici tu peux faire une boucle autour du thread courant:
    Oulà, c'est pas bon une attente active comme ceci !

    Autant faire
    c'est une attente passive...

  11. #11
    Membre du Club Avatar de Frac10
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Points : 43
    Points
    43
    Par défaut
    J'avais essayé avec join(), mais il reste toujours un problème : les processus se lancent bien dans l'ordre, mais le lancement du 2ième s'effectue avant la fin de la réception du fichier (et donc avant la fin du 1ier processus)...

    Voilà le code utilisé :
    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
    public void lanceThread() {
    	Thread t = new Thread() {
    		public void run() {
    			System.out.println("Lancement de go1()");
    			try {
    				go1();
    			} catch (Exception ex) {
    				System.err.println(ex);
    			}
    			System.out.println("go1() terminé");
    		}
    	};
    	System.out.println("Démarrage");
    	t.start();
    	System.out.println("Jonction");
    	try {
    		t.join();
    	} catch (InterruptedException iex) {
    		System.out.println("Interruption de go1()");
    	}
    	System.out.println("Lancement de go2()");
    	go2();
    }
    L'ordre des affichages sur la console est bien :
    Démarrage
    Jonction
    Lancement de go1()
    go1() terminé
    Lancement de go2()


    Mais le fichier téléchargé est introuvable puisqu'il n'est pas fini de téléchargé...

  12. #12
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par Frac10
    L'application va dans un premier temps télécharger un fichier .xls sur le net et dans un deuxième temps l'ouvrir. Donc il faut que le premier thread soit terminé quand le deuxième commence...
    Une question bête, pourquoi tu veux absolument faire le téléchargement et l'ouverture dans 2 threads différents?

  13. #13
    Membre du Club Avatar de Frac10
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Points : 43
    Points
    43
    Par défaut
    Heu t'en fais pas c'est pas une question bête, loin de là !

    Au départ je ne voulais même pas utiliser de threads et seulement lancer les appels à mes procèdures à la suite, go1() puis go2() (dans le fichier GetFile.java).
    Cela marche très bien puisque go2() attendait la fin de go1() pour se lancer.

    Sauf que j'ai voulu rajouter une barre de progression au traitement de go1() (c'est-à-dire dans le fichier qui gère le téléchargement HTTPGetFile.java) pour que çà soit plus convivial. Et ce rajout je l'ai donc fait au sein d'un thread dans le programme de téléchargement (si je ne le met pas dans un thread, l'interface de progression ne s'affiche pas... ).

    Et donc en rajoutant ce thread dans HTTPGetFile le processus go2() n'atends plus la fin du processus go1() dans GetFile...
    Et là, je dois avouer que je ne comprends rien de rien...

  14. #14
    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
    Tu t'es largement compliqué la vie pour rien !!! Tu aurais du indiquer de suite ce que tu voulais faire, et non pas comment tu voulais le faire !


    Il n'y a aucune raison d'utiliser deux threads différents pour go1() et go2(), puisqu'il s'agit du même traitement et que cela doit s'effectuer de manière séquentielle (et non pas parallèle). Donc il n'y a pas besoin de synchronisation ni de rien de tout ca...


    Citation Envoyé par Frac10
    Or au niveau du programme principal, si je mets mes 2 processus simplement à la suite, comme çà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    jbGo.addActionListener(new ActionListener() {
    	public void actionPerformed(ActionEvent e) {
    		jbGo.setEnabled(false);
    		go1();
    		go2();
    	}
    });
    ils se lancent l'un après l'autre (dans l'ordre) mais l'écran de la barre de progression ne s'affiche pas...
    Le problème n'est donc pas un problème d'ordonnancement et de synchronisation entre go1() et go2() puisqu'il suffit de les appeler l'une derrière l'autre...

    Ton problème vient du fait que l'interface graphique n'est pas mise à jour ! C'est un problème classique !

    Swing utilise un thread unique pour la mise à jour de l'interface graphique et la gestion des évenements : l'EDT. Mais si tu effectues des traitements trop long dans ce thread, ton IG ne pourra pas être actualisé et restera donc figé...

    Or la méthode actionPerformed() est appelée par l'EDT. Donc si tu y appeles directement tes méthodes cela va tout bloquer ! Il faut donc que tu effectues ces traitements dans un thread séparé (et un seul thread pour go1() et go2()).

    Le problème vient du fait que ce qui concernera l'affichage (la mise à jours du JProgressBar dans ton cas) devra être fait dans l'EDT (avec SwingUtilities.incokeLater() par exemple) sinon tu risque d'avoir des bugs graphiques...

    Pour plus de détail : Threads et performance avec Swing



    Le plus simple serait donc d'utiliser la classe SwingWorker, comme l'avait dit lxegre qui avait bien cerné le problème exact...


    a++

  15. #15
    Membre confirmé Avatar de broumbroum
    Profil pro
    Inscrit en
    Août 2006
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 406
    Points : 465
    Points
    465
    Par défaut
    Citation Envoyé par ®om
    Oulà, c'est pas bon une attente active comme ceci !

    Autant faire
    c'est une attente passive...
    Mais si tu veux lancer une commande dans le temps que tu attends la fin?

  16. #16
    Membre du Club Avatar de Frac10
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par adiGuba
    Tu t'es largement compliqué la vie pour rien !!! Tu aurais du indiquer de suite ce que tu voulais faire, et non pas comment tu voulais le faire !

    Oui effectivement je suis désolé, c'est qu'en fait au départ j'ai voulu me débrouiller tout seul en cherchant ce qui n'allait pas et en faisant des recherches sur le net. Je suis tombé sur les threads et la synchronisation et j'ai donc cru que mon problème venait de là...

    Donc comme tu l'as si bien dit et comme l'avais bien cerné Ixegre (encore désolé d'avoir continué à m'enfoncer dans les threads... ) un thread unique suffit au niveau des 2 processus go1 et go2 et le thread dans lequel j'actualisais ma progressBar ne sert à rien.

    Bref c'est bon çà marche, et je vais essayer de regarder la classe SwingWorker si elle facilite la vie.

    Merci encore à tous et encore désolé !!!

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

Discussions similaires

  1. Problème avec Hibernate Synchronizer
    Par hela.sfar dans le forum Hibernate
    Réponses: 1
    Dernier message: 29/07/2012, 01h05
  2. Réponses: 2
    Dernier message: 27/02/2012, 11h53
  3. problème avec un import et un thread
    Par cFranssen dans le forum Général Python
    Réponses: 17
    Dernier message: 22/04/2011, 17h10
  4. Problème avec Hibernate synchronizer
    Par jason69 dans le forum Hibernate
    Réponses: 2
    Dernier message: 27/08/2007, 11h35
  5. Réponses: 5
    Dernier message: 10/05/2005, 10h22

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