Problème avec NotifyAll et Thread

Le
florianter
Bonjour,
Je n'arrive pas à trouver pourquoi, ma méthode wake(), ne réveille pas la méthode wait(). Le réveille s'effectue seulement au bout du délai fixé dans wait(delai). Quelqu'un aurait il une solution svp?


public class ThreadPartie extends Thread {
Partie p;
long delai;

public ThreadPartie(Partie p, long delai) {
this.p = p;
this.delai = delai;
}

public synchronized void wake(){

this.notify();

}

public synchronized void run() {
try {
// pause

wait(delai);

} catch (InterruptedException ex) {
}
System.out.println("fin");
}
}
}

public class Principale {

public static void main(String[] args) {

Dictionnaire d = new Dictionnaire("dictionnaire");
Partie p = new Partie(d,0,200000,1);

ThreadPartie t = new ThreadPartie(p,10000);
t.start();
t.wake();

}

}
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Frederic Lachasse
Le #18265771
On Dec 29, 5:12 pm, florianter
Bonjour,
Je n'arrive pas à trouver pourquoi, ma méthode wake(), ne réveille pas la
méthode wait(). Le réveille s'effectue seulement au bout du délai f ixé dans
wait(delai). Quelqu'un aurait il une solution svp?

public class ThreadPartie extends Thread {
        Partie p;
        long delai;

        public ThreadPartie(Partie p, long delai) {
                this.p = p;
                this.delai = delai;
        }

        public synchronized void wake(){

            this.notify();

        }

        public synchronized void run() {
                try {
                        // pause

                        wait(delai);

                } catch (InterruptedException ex) {
                }
                System.out.println("fin");
                }
        }

}

public class Principale {

        public static void main(String[] args) {

                Dictionnaire d = new Dictionnaire("dict ionnaire");
                Partie p = new Partie(d,0,200000,1);

ThreadPartie t = new ThreadPartie(p,10000);
t.start();
t.wake();

        }

}



Probablement: la méthode Thread.start() n'exécute pas immediatement le
thread en appelant la méthode run() du thread. En fait, start() ne
fait qu'ajouter le thread dans une queue de thread pouvant être
exécuté selon disponibilité de resources CPU. Même sur un système
multi-processeurs, il est assez probable que le notify() soit appelé
avant le wait(), donc en fait, le notify() ne fait rien: personne
n'attend à ce moment.

En fait, la documentation de wait() conseille fortement d'utiliser wait
() seulement dans une boucle du genre:

synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}

Donc la solution est d'utiliser une variable pour signaler que le
thread principal a fini son traitement et réveille le thread:

public class ThreadPartie extends Thread {
Partie p;
long delai;
boolean reveille = false;

public ThreadPartie(Partie p, long delai) {
this.p = p;
this.delai = delai;
}
public synchronized void wake(){
this.reveille = true;
this.notify();
}
public void run() {
try {
// pause
synchronized (this) {
while (!reveille) {
wait(delai);
}
}
} catch (InterruptedException ex) {
}
System.out.println("fin");
}
}
Publicité
Poster une réponse
Anonyme