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 :

Thread et raffraichissement de l'IHM


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 11
    Points
    11
    Par défaut Thread et raffraichissement de l'IHM
    Bonjour,

    Je cherche a réaliser un projet et j'ai besoin d'un thread, mais je n'arrive pas à le coder.

    Mon projet utilise un module Arduino qui pilote une machine éjectant des pièces. Le module Arduino est relié à mon PC par le réseau et je souhaite que mon IHM (programme Java tournant sur le PC) affiche le nombre de pièces restantes.
    Jusque là, tout fonctionne; J'ai posé un bouton sur mon prog java et lorsque je clique dessus, une commande est envoyée au module arduino qui me répond en me transmettant le nombre de pièces, lequel s'affiche bien sur l'IHM.

    Je voulais donc terminer mon projet en utilisant deux boutons:
    - Le 1er qui me lancerait un thread qui réaliserait en boucle les opérations d'interrogation du module et d'affichage des quantités de pièces
    - Le deuxième qui me permettrait de stopper (ou détruire) le thread.

    Je n'arrive à rien, l'IHM se fige et le programme est complètement bloqué. Quelqu'un a-t-il une idée ?
    Je souhaitais utiliser un thread car il me semble que c'est la meilleure solution, mais je suis prêt à changer si quelqu'un me propose quelque chose qui fonctionne!


    Voici un extrait du code chargé de démarrer le thread:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	private void jButton3MouseClicked(java.awt.event.MouseEvent evt) {                                      
        {
    		T = new ThreadLecturePieces(this.ServerHostName,this.ServerPort);
    		T.run();      
        }                                     
     
        private void jButton4MouseClicked(java.awt.event.MouseEvent evt) {                                      
        {
    		T.cancel();
    	}
    ...Et voici le code de mon thread:
    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
     
    public class ThreadLecturePieces implements Runnable 
    {
        public String ServerHostName="";
        public String ServerPort="";
        public boolean Etat;
     
        ThreadLecturePieces(String Host, String Port) 	// constructeur
        {
            this.ServerHostName=Host;
            this.ServerPort=Port;
        }
     
        @Override
        public void run() 
        {
            this.Etat=true;
            while(this.Etat) 
            {
                try {
                    AcquerirNombreDePieces();
                    Thread.sleep(5000);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    break; // Sortie de la boucle infinie
                }
            }
        }
     
        public void cancel()	// Pour stopper le thread
        {
            this.Etat = false;
        }
     
        protected void AcquerirNombreDePieces()
        {
            ....
        }
    Je remercie par avances les ames charitables qui voudraient bien se pencher sur mon problème, ça fait 3 jours que je galère avec ce $@* de projet qui doit être prêt pour jeudi... Je n'en dors plus de la nuit

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


    Déjà désolé de te l'apprendre... mais tu ne crée pas de Thread !
    Tu crées juste un objet "Runnable" que tu exécutes directement (dans le thread graphique, ce qui bloque complètement ton interface).

    Il faut créer un objet Thread, et utiliser la méthode start() pour le démarrer (et surtout pas run() !)
    Cela exécutera la méthode run() du Thread (ou du Runnable que tu lui passes) dans un thread séparé...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	private void jButton3MouseClicked(java.awt.event.MouseEvent evt) {
    		T = new Thread(new ThreadLecturePieces(this.ServerHostName,this.ServerPort));
    		T.start();
    	}


    Pour arrêter le thread ta solution est correct, si ce n'est qu'il est préférable de passer la variable "Etat" en volatile, pour éviter que la JVM n'optimise trop les accès à la variable.




    Toutefois, il serait plus simple d'utiliser les fonctions d'interruptions du Thread, qui sont fait pour cela :
    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
    public class ThreadLecturePieces implements Runnable {
    	private final String ServerHostName;
    	private final String ServerPort;
     
    	ThreadLecturePieces(String Host, String Port) {
    		this.ServerHostName = Host;
    		this.ServerPort = Port;
    	}
     
    	@Override
    	public void run() {
    		try {
    			while (Thread.interrupted()==false) {
    				AcquerirNombreDePieces();
    				Thread.sleep(5000);
    			}
    		} catch (InterruptedException ex) {
    			// Exception à ignorer
    			// On a reçu un interruption pendant le 'sleep()'
    			// Ca permet de sortir de la boucle et de finir le thread
    		}
    	}
     
    	protected void AcquerirNombreDePieces() {
    		// ....
    	}
    }
    Du coup on "arrête" le thread via sa méthode interrupt() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	private void jButton4MouseClicked(java.awt.event.MouseEvent evt) {
    		if (T!=null) {
    			T.interrupt();
    		}
    	}

    Sinon quelques remarques :
    • Attention aux conventions de nommages.
      Les noms d'attributs, de paramètres, de variables locales ou de méthode commencent par une minuscule...
    • Les attributs devraient plutôt être déclarées en private par défaut.
      Et en final si leurs valeurs ne doit pas changer une fois l'objet créé.
      Quand à l'initialisation à "" elle est inutile...


    a++

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Bonjour adiGuba,

    J'ai fais comme tu m'as expliqué, IL Y A DU MIEUX (le thread a l'air de fonctionner) mais je ne vois pas trop la différence par rapport à ce que j'avais fait.

    Voila la nouvelle version
    Dans mon IHM:
    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
     
    	private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {
    		jTabbedPane1.setSelectedIndex(1);
            jTabbedPane1.setEnabled(true);
            if (T!=null) 
            {
                T.start();
                System.out.println("Thread lance");
            }
     
        }
     
    	private void jButton4MouseClicked(java.awt.event.MouseEvent evt) {                                      
            if (T!=null) 
            {
                T.interrupt();
                System.out.println("Thread interrompu");
            }
        }
    Et dans le thead:
    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 run() {
    		try {
    				while (Thread.interrupted()==false) {
    						AcquerirNombreDePieces();
    						Thread.sleep(5000);
    				}
    		} catch (InterruptedException ex) {
    				// Exception à ignorer
    				// On a reçu un interruption pendant le 'sleep()'
    				// Ca permet de sortir de la boucle et de finir le thread
    		}
    }
     
    void start() {
    	//throw new UnsupportedOperationException("Not yet implemented");
    	this.run();
    }
     
    void interrupt() {
    	//throw new UnsupportedOperationException("Not yet implemented");
    	this.interrupt();
    }
    Je ne vois pas vraiment la différence par rapport à ce que j'avais fait. Est-ce vraiment différent d'appeler la méthode run depuis la méthode start plutot que depuis l'IHM ?

    Ce qui va mieux:
    • Le thread va bien réaliser régulièrement l'acquisition du nombre de pièces.


    Ce qui ne fonctionne toujours pas:
    • L'IHM n'est pas rafraichie. J'ai bêtement réalisé un programme avec deux onglets. Le premier est celui de la configuration (pour entrer l'adresse ip,etc). Il contient les boutons pour lancer et arrêter le thread. Lorsque je lance le thread, je suis sensé basculer sur le deuxième onglet (visualisation du nombre de pièces).

    • Après le lancement du thread, l'IHM est figée et je reste sur le premier onglet. C'est d'autant plus triste que je veux faire un thread justement pour que l'IHM ne se fige pas!


    Je ne peux pas stopper le thread. Le bouton n'a pas l'air de répondre, mais peut-être est-ce du au fait que l'IHM est figée???

    Sinon, je n'ai pas compris le sens de ta phrase:
    Citation Envoyé par adiGuba Voir le message
    Pour arrêter le thread ta solution est correct, si ce n'est qu'il est préférable de passer la variable "Etat" en volatile, pour éviter que la JVM n'optimise trop les accès à la variable.
    Je ne sais pas ce que cela veut dire, ni comme faire pour passer cette variable en volatile...


    ...Et par rapport à tes remarques, je fais mon mea culpa, il me reste des mauvaises habitudes que j'essaie de corriger petit à petit. Par contre, c'est Netbeans qui me force à initialiser mes string ainsi, sinon il fait un warning (qui n'est pas joli!).


    En tout cas, merci pour ton aide précieuse...

  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
    Citation Envoyé par bob1973 Voir le message
    Je ne vois pas vraiment la différence par rapport à ce que j'avais fait. Est-ce vraiment différent d'appeler la méthode run depuis la méthode start plutot que depuis l'IHM ?
    Tu ne DOIS PAS faire de méthode start() ! Ni interrupt() d'ailleurs !
    Regarde bien le code que je t'ai donné, il n'y a rien de tel.

    Il faut que tu crée un objet de type Thread comme indiqué dans mon premier message.
    C'est cet objet Thread qui possède déjà une méthode start(), et appeler cette méthode créer un thread et y exécute la méthode run().


    Il ne faut pas appeler directement la méthode comme tu le fais, car sinon elle s'exécute dans le thread courant (ce qui provoque l'interface figé).


    En fait c'est ta classe ThreadLecturePieces qui est mal nommé car ce n'est pas un Thread. Elle devrait se nommer LecturePieces tout court par exemple...


    Dans le code que je t'ai donné, je crée vraiment un thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    T = new Thread(new ThreadLecturePieces(this.ServerHostName,this.ServerPort));



    a++

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Merci pour ta réponse rapide!

    En fait, j'avais d'abord compris correctement et essayé de suivre tes instructions, mais je n'avais pas remarqué la différence entre ton instanciation de T et la mienne. Du coup, il ne connaissait pas les méthodes start() et interrupt().
    Je les ai ensuite codé en pensant avoir mal compris ce que tu avais pourtant bien expliqué!

    Du coup ça marché parfaitement et je ne te remercierais jamais assez. Je n'ai pas perdu mon week-end à bosser sur ce projet pour des clous.

    Pour revenir sur mon erreur, je pensais qu'en écrivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class ThreadLecturePieces implements Runnable
    cela définissait automatiquement un thread.

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

Discussions similaires

  1. Mélange de threads Boost et d'une IHM Qt
    Par petebull1976 dans le forum Multithreading
    Réponses: 11
    Dernier message: 05/07/2011, 00h57
  2. Thread : ne marche pas avec IHM PyGTK
    Par syrius31 dans le forum Général Python
    Réponses: 2
    Dernier message: 18/03/2011, 07h13
  3. Thread/Mise a jour d'IHM
    Par davids75014 dans le forum Interfaces Graphiques en Java
    Réponses: 7
    Dernier message: 04/06/2007, 14h44
  4. [VB.NET][VS2003] Threads et IHM
    Par toniolol dans le forum Windows Forms
    Réponses: 7
    Dernier message: 27/04/2006, 13h54
  5. [SWT]mise a jour ihm SWT par un thread
    Par will82 dans le forum SWT/JFace
    Réponses: 1
    Dernier message: 06/08/2004, 11h37

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