Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Problème avec NotifyAll et Thread

1 réponse
Avatar
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();

}

}

1 réponse

Avatar
Frederic Lachasse
On Dec 29, 5:12 pm, florianter wrote:
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");
}
}