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

Java Discussion :

Problème de wait and notify


Sujet :

Java

  1. #1
    Membre à l'essai
    Profil pro
    CTO
    Inscrit en
    Février 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : CTO

    Informations forums :
    Inscription : Février 2009
    Messages : 20
    Points : 16
    Points
    16
    Par défaut Problème de wait and notify
    Bonjours à tous,

    Je débute dans les Treads, et dans un but pédagogique je doit réaliser l'exercice suivant :

    <italique>
    Un groupe d'amis décide de faire des promenades, cependant les membres du groupe ne marchent pas à la même vitesse. Ils ont donc prévu de faire 5 tours d’un parcours cyclique en forêt avec 2 rendez-vous : marche individuelle sur la partie A, attente au RDV1, puis marche individuelle sur la partie B, puis RDV2, etc. Chaque marcheur sera représenté par un thread Java avec sa propre IHM (Frame + textArea). Ces threads passeront un temps aléatoire dans la partie A qui pourra être matérialisé par plusieurs tirages aléatoires. (Il s’agit de faire 1000 mètres en additionnant des tirages aléatoires de 100m. Les marcheurs se synchronisent au rendez-vous RDV1 (donc les premiers arrivés attendent le dernier). Puis ils passeront un temps aléatoire dans la partie B. Ils seront synchronisés au rendez-vous RDV2. Ensuite chaque thread recommence la partie A du parcours en forêt.

    Rédigez une classe Marcheur (avec IHM) représentant les activités d'un marcheur.
    Rédigez une classe RDV qui permet l'organisation des rendez-vous. Cette classe dispose d'un compteur représentant le nombre de personnes attendues au RDV. Chaque marcheur incrémente ce compteur à son arrivée au RDV et se met en sommeil avec l’aide de la méthode wait(). Le dernier marcheur ne doit pas utiliser la méthode wait() mais faire appel à la méthode notifyAll() pour réveiller tous les autres marcheurs.
    Rédigez la classe Principale qui initialise le programme avec 5 marcheurs puis 10 marcheurs.
    </italique>

    Voici mes classes (c'est un peu crade je sais mais je peaufinerai quand ça marchera ) :

    Marcheur.java
    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
     
    public class Marcheur implements Runnable{
        private String label;
        private Color couleur;
        private int position;
        private int arrivee;//La position de l'arrivé en mètre
     
        private JFrame fen;
        private JLabel avancement;//Pour afficher dans l'interface graphique l'avancement actuel
     
        //static Marcheur dernier_arrive;
        static RDV prochain_rdv;
        static RDV rdv1;
        static RDV rdv2;
     
        public Marcheur(String label, Color couleur, int arrive) {
            //On commence par récupérer des infos sur le prochain rdv pour les afficher
            String label_prochain_rdv = null;
     
            if( prochain_rdv != null){
                label_prochain_rdv = "Prochain RDV : " + prochain_rdv.getLabel_rdv();
            }else{
                label_prochain_rdv = "Prochain RDV : inconnu";
            }
     
            this.label = label;
            this.couleur = couleur;
            this.position = 0;
            this.arrivee = arrive;
            this.avancement = new JLabel("Marcheur " + label + " " + label_prochain_rdv + " " + position + " / "+arrivee);
     
     
            //Construction de la fenetre
            fen = new JFrame();
            fen.getContentPane().add(avancement);
            fen.setTitle("Test marcheur");
            fen.setSize(190, 80);
            fen.setLocation(200, 100+(Integer.parseInt(label)*80));
     
            fen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            fen.setVisible(true);
     
     
        }
     
        public String getLabel(){
            return this.label;
        }
     
        /**Permet de réinitialiser un Marcheur pour qu'il soit prêt à repartir
        */
        public void initialiser(){
            this.position = 0;
            //this.avancement.setText("Marcheur " + label + " " + prochain_rdv.getLabel_rdv() + " " + position + " / "+arrivee);
        }
     
        //Pour rensigner les rdv connu de tous les marcheurs (variable static)
        public void initialiserRDV(RDV rdvA, RDV rdvB, RDV proch_rdv){
            Marcheur.rdv1 = rdvA;
            Marcheur.rdv2 = rdvB;
            Marcheur.prochain_rdv = proch_rdv;
        }
     
        //Pour tous les marcheur, indique le prochain rendez-vous
        public void setProchainRDV(RDV rdv){
            Marcheur.prochain_rdv = rdv;
        }
     
        public boolean estArrive(){
            return arrivee - position == 0;
        }
     
        public int alea(int valeur){
            Random generator = new Random();
            return generator.nextInt(valeur+1);
        }
     
        public void pause(int valeur){
            try {
                Thread.sleep(valeur);
            } catch (InterruptedException ex) {
                Logger.getLogger(Marcheur.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
     
        private void avancer(){
            int distance_parcourue = alea(3)*100;//On avance par 100 mètres
            this.position += distance_parcourue;
     
            //On arrête le marcheur à l'arrivée si il est en position de la dépasser. 
            if( position > arrivee){
                position = arrivee;
            }
            avancement.setText("Marcheur " + label + " " +prochain_rdv.getLabel_rdv() + " " + position + " / "+arrivee);
        }
     
        /**Pour passer du rdv 1 au 2 ou vice versa */
        void changer_rdv(){
            if( Marcheur.prochain_rdv == Marcheur.rdv1){
                Marcheur.prochain_rdv = Marcheur.rdv2;
            }else{
                Marcheur.prochain_rdv = Marcheur.rdv1;
            }
            Marcheur.prochain_rdv.nb_marcheur_arrive = 0;//De nouveau, plus personne n'est arrivé
        }
     
        //Gère l'arrivé au rdv, si on est le dernier on fait un notify sur les autres, sinon on attends
        synchronized void arriver(){
            if( Marcheur.prochain_rdv.tous_arrive()){
                this.notifyAll();
                System.out.println("\n RDV suivant ! \n");
                //changer_rdv();
     
            }else{
                try {
                    this.wait();
                } catch (InterruptedException ex) {
                    Logger.getLogger(Marcheur.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
     
        void aller_au_rdv(){
            while( !estArrive()){
                avancer();
                pause(1000);
            }
            System.out.println(label + "est arrivé.");
            Marcheur.prochain_rdv.marcheur_arrive(this);//On indique au rdv qu'on est arrive
            this.arriver();
        }
     
        @Override
        public void run(){
            //aller_au_rdv();
            for(int i=0 ; i<5 ; i++){
                aller_au_rdv();
                this.position = 0;//Si on execute cette ligne, c'est qu'on a été reveillé eet qu'on est passé au rdv suivant
            }
        }
    }
    RDV.java

    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 RDV{
        final String label_rdv;
        final int nb_marcheur_total;
        int nb_marcheur_arrive;
        //List <Marcheur>liste_marcheur;
     
        RDV(int nb_marcheur_total, String label){
            this.nb_marcheur_total = nb_marcheur_total;
            //this.liste_marcheur = new ArrayList<Marcheur>();
            this.nb_marcheur_arrive = 0;
            this.label_rdv = label;
        }
     
        public String getLabel_rdv() {
            return label_rdv;
        }
     
        //Cette méthode doit absolument être synchronisé, sinon grave incohérence
        synchronized boolean tous_arrive(){
            return nb_marcheur_arrive == nb_marcheur_total;
        }
     
        synchronized void marcheur_arrive(Marcheur arrivant){
            nb_marcheur_arrive++;
        }
    }
    Et enfin, la classe principale qui construit les différents objet puis lance le tout.

    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
     
    public class Principal {
        Marcheur[] marcheurs;
        Thread[] threads;
        RDV rdv1, rdv2;
     
        Principal(int nb_marcheur){
            marcheurs = new Marcheur[nb_marcheur];
            threads = new Thread[5];
     
            //Création des 2 lieux de rendez-vous
            rdv1 = new RDV(nb_marcheur, "rdv1");
            rdv2 = new RDV(nb_marcheur, "rdv2");
     
            //On cré chaque marcheur, on lui associe le rdv1, et on lui associe un thread
            for(int i=0 ; i<nb_marcheur ; i++){
                marcheurs[i] = new Marcheur(i+"", Color.RED, 1000);
                threads[i]   = new Thread(marcheurs[i]);
            }
            marcheurs[0].initialiserRDV(rdv1, rdv2, rdv1);
     
            rdv1 = new RDV(nb_marcheur, "rdv1");
            rdv2 = new RDV(nb_marcheur, "rdv2");
        }
     
        void lancer(){
            for(int i=0 ; i<marcheurs.length ; i++){
                threads[i].start();
            }
        }
     
        public static void main(String[] args){
            Principal p = new Principal(5);
            p.lancer();
        }
    }
    Sauf que voila, tout marche mais au bout du premier rdv les Thread en attentes ne sont pas réveillé...
    Seul le dernier Thread (qui fait le notifyAll() ) repart.
    Et je ne comprends pas pourquoi.
    J'ai beau relire la doc, le cours, il y a un truc qui m'a échappé et que je n'ai pas saisi...

    Pourriez-vous m'éclairer ?

    Merci d'avance.

  2. #2
    Membre éclairé
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 471
    Points : 831
    Points
    831
    Par défaut
    Bonjour Drife

    NotifyAll, comme le dit la javadoc ne fonctionne que pour le même objet. Tes marcheurs sont 5 objets différents,

    marcheurs[i] = new Marcheur(i+"", Color.RED, 1000);
    donc le notifyAll ne fonctionnera que pour l'objet qui l'a executé (le dernier marcheur arrivé).

    Cordilement
    Page sur Developpez : http://pbriand.developpez.com

  3. #3
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    Par défaut
    Utilise un ThreadGroup.

    A+.

  4. #4
    Membre éclairé
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 471
    Points : 831
    Points
    831
    Par défaut
    Tu peux aussi faire partagé un objet en commun a tes 5 marcheur et faire le wait et notifyAll sur cet objet. Je l'ai testé et cela fonctionne, mais comme c'es un exercice, il faut que tu cherche un peu la solution.
    Page sur Developpez : http://pbriand.developpez.com

  5. #5
    Membre à l'essai
    Profil pro
    CTO
    Inscrit en
    Février 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : CTO

    Informations forums :
    Inscription : Février 2009
    Messages : 20
    Points : 16
    Points
    16
    Par défaut Merci
    Bonjour,

    Grâce à vos proposition j'ai mieux compris comment ça fonctionnait et j'ai délocalisé le wait et notify dans la ressource commune, à savoir dans le RDV.java. Au lieux d'avoir 5 piles d'exécution différentes...

    Si jamais ça intéresse quelqu'un, voici comment j'ai fait :

    RDV.java

    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
     
    public class RDV{
        final String label_rdv;
        final int nb_marcheur_total;
        int nb_marcheur_arrive;
        List <Marcheur>liste_marcheur;
     
        RDV(int nb_marcheur_total, String label){
            this.nb_marcheur_total = nb_marcheur_total;
            this.liste_marcheur = new ArrayList<Marcheur>();
            this.nb_marcheur_arrive = 0;
            this.label_rdv = label;
        }
     
        public String getLabel_rdv() {
            return label_rdv;
        }
     
        //Cette méthode doit absolument être synchronisé, sinon grave incohérence
        synchronized boolean tous_arrive(){
            return nb_marcheur_arrive == nb_marcheur_total;
        }
     
        synchronized void marcheur_arrive(Marcheur arrivant){
            nb_marcheur_arrive++;
     
            if( ! tous_arrive()){
                try {
                    wait();//Met en pause le Thread qui accède à la méthode, en l'occurence un marcheur
                } catch (InterruptedException ex) {
                    Logger.getLogger(RDV.class.getName()).log(Level.SEVERE, null, ex);
                }
            }else{
                System.out.println("Le dernier arrive est : "+ arrivant.getLabel() + "\n RDV suivant ! \n");
                notifyAll();//Fait repartir tous les autres Thread qui étaient bloqué dans la méthode
                arrivant.changer_rdv();//Et change de rendez-vous ;-)
            }
        }
    }
    Marcheur.java

    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    public class Marcheur implements Runnable{
        private String label;
        private Color couleur;
        private int position;
        private int arrivee;//La position de l'arrivé en mètre
     
        private JFrame fen;
        private JLabel avancement;//Pour afficher dans l'interface graphique l'avancement actuel
     
        static RDV prochain_rdv;
        static RDV rdv1;
        static RDV rdv2;
     
        public Marcheur(String label, Color couleur, int arrive) {
            //On commence par récupérer des infos sur le prochain rdv pour les afficher
            String label_prochain_rdv = null;
     
            if( prochain_rdv != null){
                label_prochain_rdv = "Prochain RDV : " + prochain_rdv.getLabel_rdv();
            }else{
                label_prochain_rdv = "Prochain RDV : inconnu";
            }
     
            this.label = label;
            this.couleur = couleur;
            this.position = 0;
            this.arrivee = arrive;
            this.avancement = new JLabel("Marcheur " + label + " " + label_prochain_rdv + " " + position + " / "+arrivee);
     
     
            //Construction de la fenetre
            fen = new JFrame();
            fen.getContentPane().add(avancement);
            fen.setTitle("Test marcheur");
            fen.setSize(190, 80);
            fen.setLocation(200, 100+(Integer.parseInt(label)*80));
     
            fen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            fen.setVisible(true);
     
     
        }
     
        public String getLabel(){
            return this.label;
        }
     
        //Pour rensigner les rdv connu de tous les marcheurs (variable static)
        public void initialiserRDV(RDV rdvA, RDV rdvB, RDV proch_rdv){
            Marcheur.rdv1 = rdvA;
            Marcheur.rdv2 = rdvB;
            Marcheur.prochain_rdv = proch_rdv;
        }
     
        //Pour tous les marcheur, indique le prochain rendez-vous
        public void setProchainRDV(RDV rdv){
            Marcheur.prochain_rdv = rdv;
        }
     
        public boolean estArrive(){
            return arrivee - position == 0;
        }
     
        public int alea(int valeur){
            Random generator = new Random();
            return generator.nextInt(valeur+1);
        }
     
        public void pause(int valeur){
            try {
                Thread.sleep(valeur);
            } catch (InterruptedException ex) {
                Logger.getLogger(Marcheur.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
     
        private void avancer(){
            int distance_parcourue = alea(3)*100;//On avance par 100 mètres
            this.position += distance_parcourue;
     
            //On arrête le marcheur à l'arrivée si il est en position de la dépasser. 
            if( position > arrivee){
                position = arrivee;
            }
            avancement.setText("Marcheur " + label + " " +prochain_rdv.getLabel_rdv() + " " + position + " / "+arrivee);
        }
     
        /**Pour passer du rdv 1 au 2 ou vice versa */
        void changer_rdv(){
            if( Marcheur.prochain_rdv == Marcheur.rdv1){
                Marcheur.prochain_rdv = Marcheur.rdv2;
            }else{
                Marcheur.prochain_rdv = Marcheur.rdv1;
            }
            Marcheur.prochain_rdv.nb_marcheur_arrive = 0;//De nouveau, plus personne n'est arrivé
        }
     
        void aller_au_rdv(){
            while( !estArrive()){
                avancer();
                pause(1000);
            }
            System.out.println(label + "est arrivé.");
            Marcheur.prochain_rdv.marcheur_arrive(this);//On indique au rdv qu'on est arrive
        }
     
        @Override
        public void run(){
            for(int i=0 ; i<5 ; i++){
                aller_au_rdv();
                this.position = 0;//Si on execute cette ligne, c'est qu'on a été reveillé eet qu'on est passé au rdv suivant
            }
            System.out.println("La petite promenade de santé est fini pour "+this.getLabel()+". C'est l'heure de mourrir !");
        }
    }
    Merci beaucoup

  6. #6
    Membre éclairé
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 471
    Points : 831
    Points
    831
    Par défaut
    Bien trouvé.

    J'avais fait un peu différemment. J'ai passé le même objet à tous les marcheurs et j'ai fait mon wait et notifyAll sur cet objet.

    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    import java.awt.Color;
    import java.util.Random;
    import java.util.logging.Level;
    import java.util.logging.Logger;
     
    import javax.swing.JFrame;
    import javax.swing.JLabel;
     
     
    public class Marcheur implements Runnable{
        private String label;
        private Color couleur;
        private int position;
        private int arrivee;//La position de l'arrivé en mètre
     
        private JFrame fen;
        private JLabel avancement;//Pour afficher dans l'interface graphique l'avancement actuel
        private Object waitingObj;
        private int step;
     
        //static Marcheur dernier_arrive;
        static RDV prochain_rdv;
        static RDV rdv1;
        static RDV rdv2;
     
        public Marcheur(String label, Color couleur, int arrive, Object obj) {
            //On commence par récupérer des infos sur le prochain rdv pour les afficher
            waitingObj = obj;
            String label_prochain_rdv = null;
     
            if( prochain_rdv != null){
                label_prochain_rdv = "Prochain RDV : " + prochain_rdv.getLabel_rdv();
            }else{
                label_prochain_rdv = "Prochain RDV : inconnu";
            }
     
            this.label = label;
            this.couleur = couleur;
            this.position = 0;
            this.arrivee = arrive;
            this.avancement = new JLabel("Marcheur " + label + " " + label_prochain_rdv + " " + position + " / "+arrivee);
     
     
            //Construction de la fenetre
            fen = new JFrame();
            fen.getContentPane().add(avancement);
            fen.setTitle("Test marcheur");
            fen.setSize(290, 80);
            fen.setLocation(200, 100+(Integer.parseInt(label)*80));
     
            fen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            fen.setVisible(true);
     
     
        }
     
        public String getLabel(){
            return this.label;
        }
     
        /**Permet de réinitialiser un Marcheur pour qu'il soit prêt à repartir
        */
        public void initialiser(){
            this.position = 0;
            //this.avancement.setText("Marcheur " + label + " " + prochain_rdv.getLabel_rdv() + " " + position + " / "+arrivee);
        }
     
        //Pour rensigner les rdv connu de tous les marcheurs (variable static)
        public void initialiserRDV(RDV rdvA, RDV rdvB, RDV proch_rdv){
            Marcheur.rdv1 = rdvA;
            Marcheur.rdv2 = rdvB;
            Marcheur.prochain_rdv = proch_rdv;
        }
     
        //Pour tous les marcheur, indique le prochain rendez-vous
        public void setProchainRDV(RDV rdv){
            Marcheur.prochain_rdv = rdv;
        }
     
        public boolean estArrive(){
            return arrivee - position == 0;
        }
     
        public int alea(int valeur){
            Random generator = new Random();
            return generator.nextInt(valeur+1);
        }
     
        public void pause(int valeur){
            try {
                Thread.sleep(valeur);
            } catch (InterruptedException ex) {
                Logger.getLogger(Marcheur.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
     
        private void avancer(){
            int distance_parcourue = alea(3)*100;//On avance par 100 mètres
            this.position += distance_parcourue;
     
            //On arrête le marcheur à l'arrivée si il est en position de la dépasser. 
            if( position > arrivee){
                position = arrivee;
            }
            avancement.setText("Marcheur " + label + " Step=" + step + ":"  +prochain_rdv.getLabel_rdv() + " " + position + " / "+arrivee);
        }
     
        /**Pour passer du rdv 1 au 2 ou vice versa */
        void changer_rdv(){
            if( Marcheur.prochain_rdv == Marcheur.rdv1){
                Marcheur.prochain_rdv = Marcheur.rdv2;
            }else{
                Marcheur.prochain_rdv = Marcheur.rdv1;
            }
            Marcheur.prochain_rdv.nb_marcheur_arrive = 0;//De nouveau, plus personne n'est arrivé
            avancement.setText("Marcheur " + label + " Step=" + step + ":"  +prochain_rdv.getLabel_rdv() + " " + position + " / "+arrivee);
        }
     
        //Gère l'arrivé au rdv, si on est le dernier on fait un notify sur les autres, sinon on attends
        void arriver(){
            if( Marcheur.prochain_rdv.tous_arrive()){
              synchronized (waitingObj) {
                waitingObj.notifyAll();
              }
              System.out.println("\n RDV suivant ! \n");
              changer_rdv();
     
            }else{
                try {
                  synchronized (waitingObj) {
                    waitingObj.wait();
                  }  
                  System.out.println("\n RDV suivant ! \n");
                  changer_rdv();
                } catch (InterruptedException ex) {
                    Logger.getLogger(Marcheur.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
     
        void aller_au_rdv(){
            while( !estArrive()){
                avancer();
                pause(1000);
            }
            System.out.println(label + "est arrivé.");
            Marcheur.prochain_rdv.marcheur_arrive(this);//On indique au rdv qu'on est arrive
            arriver();
        }
     
        @Override
        public void run(){
            //aller_au_rdv();
            for(step=0 ; step<5 ; step++){
                aller_au_rdv();
                this.position = 0;//Si on execute cette ligne, c'est qu'on a été reveillé eet qu'on est passé au rdv suivant
            }
        }
    }
    Page sur Developpez : http://pbriand.developpez.com

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

Discussions similaires

  1. [Thread] wait and notify
    Par storm_2000 dans le forum Concurrence et multi-thread
    Réponses: 0
    Dernier message: 27/10/2009, 22h24
  2. Problème Thread wait / Notify
    Par tiamat dans le forum Concurrence et multi-thread
    Réponses: 17
    Dernier message: 28/05/2009, 12h24
  3. Problème entre repaint and wait
    Par anarkia dans le forum EDT/SwingWorker
    Réponses: 2
    Dernier message: 06/04/2009, 02h08
  4. [MySQL] probléme select opérateur AND
    Par Anardil dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 11/07/2007, 14h48
  5. [JTable]Problême de Look and Feel???
    Par D-Phaz dans le forum Composants
    Réponses: 1
    Dernier message: 05/08/2005, 15h24

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