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

avec Java Discussion :

Attendre qu'un attribut change de valeur pour communiquer entre deux Thread .


Sujet :

avec Java

  1. #1
    Membre habitué
    Avatar de moithibault
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2009
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Juin 2009
    Messages : 124
    Points : 142
    Points
    142
    Par défaut Attendre qu'un attribut change de valeur pour communiquer entre deux Thread .
    Bonsoir ,
    J'ai un programme qui doit attendre un évenment qui se passe pas dans sa classe (une reception de message par socket , qu'un autre thread s'occupe ) Une fois que le message est reçu , pour communiquer avec mon autre thread j'ai pensé à faire un attribu String message initialisé à null et lorsque que je reçois mon message dans mon autre classe je met cette attribu à la valeur reçu (différente de null) . Et dans le thread pour attendre je fais while(this.message==null){} , 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
     
    public class Match implements Runnable{
    private String message=null;
    //...constructeur
    public  void run(){
                 System.out.println("attente1");
                 while(this.message==null){}
                 System.out.println("youpi");
    }
    public void setMessage(String m) {
                 this.message=m;
    }
    }
    //Et dans l'autre thread :
    public class Autre implements Runnable{
     
    public void run(){
         ................................
         if(...){
             match.setMessage(xxx);
         }
    }
    J'ai fait tout les vérification possible pour vous dire que l'attribut this.message se change trés bien (test dans la méthode setMessage() , mais apparemment le run() du Thread n'en prend pas compte dans la boucle while ) .

    Bon ensuite , dans le cadre de mon programme il me fallait un Timer , c'est à dire au bout de x secondes on regarde si on a reçu le message ou pas .

    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
     
    public class Match implements Runnable{
    private String message=null;
    //...constructeur
    public  void run(){
                 System.out.println("attente1");
                 Thread.sleep(xtemps);
                 if(this.message!=null)
                     System.out.println("youpi");
                 else
                      System.out.println("Pas dans les temps");
    }
    public void setMessage(String m) {
                 this.message=m;
    }
    }
    //Et dans l'autre thread :
    public class Autre implements Runnable{
     
    public void run(){
         ................................
         if(...){
             match.setMessage(xxx);
         }
    }
    Ce code a bien marché , mais à partir de là mon Thread va forcémment attendre xxTemps et si on reçoit le message avant on est marron , il faut atendre .
    J'ai pensé à la méthode notify() qui "r"veilleré" mon Thread , donc j'ai essayé ça :

    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 Match extends Thread{
    private String message=null;
    //...constructeur
    public  void run(){
                 System.out.println("attente1");
                 Thread.sleep(xtemps);
                 if(this.message!=null)
                     System.out.println("youpi");
                 else
                      System.out.println("Pas dans les temps");
    }
    public void setMessage(String m) {
                 this.message=m;
    }
    }
    //Et dans l'autre thread :
    public class Autre implements Runnable{
     
    public void run(){
         ................................
         if(...){
             match.setMessage(xxx);
             match.notify();
         }
    }
    Mais lorsque notify() est appelé j'ai l'exception : java.lang.IllegalMonitorStateException .

    Du coup j'ai cherché un peu sur le net , j'ai essayé d'ajouter le mot clé synchronized à mes méthodes mais en vain .

    Si vous avez des solutions à me proposer , surtout pour le second prblème (c'est à dire avec l'utilisation du Time) ! Et sinon au problème initial !

    Meci beaucoup!

  2. #2
    Membre expérimenté Avatar de Nico02
    Homme Profil pro
    Developpeur Java/JEE
    Inscrit en
    Février 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Developpeur Java/JEE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 728
    Points : 1 622
    Points
    1 622
    Par défaut
    Salut,
    Pour synchroniser tes deux Threads tu peux utiliser les Semaphore

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Citation Envoyé par biot22 Voir le message
    J'ai fait tout les vérification possible pour vous dire que l'attribut this.message se change trés bien (test dans la méthode setMessage() , mais apparemment le run() du Thread n'en prend pas compte dans la boucle while ) .
    Normal, le compilateur n'a pas de raison de penser que plusieurs threads sont impliqués dans l'exécution de ce code.
    Ce qu'il voit, lui, c'est que la boucle est vide, donc, entre autres, elle ne peut pas changer la valeur de message. Par conséquent rien ne peut changer la valeur de message, et donc cette valeur ne change pas.
    Conclusion du compilateur : ou bien on n'entre pas du tout dans la boucle, ou bien on n'en sort pas. C'est l'un ou l'autre.

    Pour régler ça, il suffit de déclarer que le membre message est volatile : peut être modifié par d'autres threads. Le compilateur va donc retourner chercher la valeur de message à chaque fois qu'on lui demande de la lire, donc à chaque boucle.

    ... Ce qui explique cela, mais une boucle d'attente active, c'est mal.

    Mieux vaut synchroniser :

    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 class Match implements Runnable{
    private String message=null;
    //...constructeur
    public  void run(){
      System.out.println("attente1");
      while(true) {
        synchronized(this) { // lock sur l'objet match
          if(message == null) {
            wait(); // attendre d'être notifé. Le lock est libéré en attendant.
          } else {
            break; // sortir de la boucle
          }
        }
      }
      System.out.println("youpi");
    }
    public synchronized void setMessage(String m) {
      this.message=m;
      notify(); // notifie le thread en attente que la valeur a changé.
      // Il se réveillera et reprendra le lock dès que celui-ci l'aura lâché
      // en sortant de cette méthode synchronized
    }
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Attendre qu'un attribut change de valeur pour communiquer entre deux classes
    Par moithibault dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 08/07/2011, 00h54
  2. Utilisation de /proc pour communiquer entre deux process
    Par Mokhtar BEN MESSAOUD dans le forum Linux
    Réponses: 8
    Dernier message: 11/06/2008, 16h52
  3. Réponses: 1
    Dernier message: 26/03/2007, 13h58
  4. condition pour afficher entre deux dates
    Par forbans dans le forum Access
    Réponses: 1
    Dernier message: 13/06/2006, 10h13
  5. [VB.NET] Passer une valeur de control entre deux form
    Par TheMacleod dans le forum Windows Forms
    Réponses: 5
    Dernier message: 27/12/2005, 12h07

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