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

Langage Java Discussion :

wait() , notify() et notifyAll()


Sujet :

Langage Java

  1. #1
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut wait() , notify() et notifyAll()
    Bonjour,

    J'ai un probleme avec les méthodes wait(), notify() et notifyAll() appliquées aux threads...
    D'aprés ce que j'ai compris elles sont utiles pour la synchronisation des threads mais je ne parvient pas a comprendre comment les utiliser et laquelle utiliser quand...

    Si il vous est possible de me l'expliquer simplement ou de me dire ou je pourrai trouver un bon tuto assez clair je suis preneur.

    merci pour votre aide.
    "La seule chose dont je sois certain, c'est que je doute"
    j'ai cassé ma boule de cristal veuillez être clair et précis dans vos propos
    compilateur - 1 nayah - 0
    PS : je suis un

  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,


    Ces méthodes s'utilisent uniquement dans les blocs synchronized et sur l'objet utilisé comme lock. Pour rappel pour rentrer dans un bloc synchronized un thread doit acquérir le lock, et tout les autres threads qui tente d'acquérir ce même lock sont mis en sommeil jusqu'à qu'il soit disponible.

    Lorsqu'on appelle wait() le thread courant s'endort et libère le verrou associé au bloc synchronized :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	// On essaye de récupérer le verrou associé à lock
    	// -> S'il est disponible on rentre dans le block synchronized
    	// -> Sinon le thread est endormi en attendant qu'il soit libéré
    	synchronized (lock) {
     
    		// wait() endort le thread courant et libère le verrou associé à lock
    		// -> Pour sortir du wait() il faut que le thread soit réveillé par notify()
    		// ET que le verrou soit à nouveau disponible
    		lock.wait();
     
    	}
    Ce code endort le thread courant et libère le verrou 'lock', qui peut ainsi être utilisé par un autre thread....



    notify() et notifyAll() permettent de réveiller un thread ou tout les threads qui se sont endormis sur le lock, ainsi si depuis un autre thread on a ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	// On essaye de récupérer le verrou associé à lock
    	// -> S'il est disponible on rentre dans le block synchronized
    	// -> Sinon le thread est endormi en attendant qu'il soit libéré
    	synchronized (lock) {
     
    		// notify() permet simplement de réveiller un autre thread
    		// qui s'est endormi avec wait() sur le même lock
    		// -> Le thread courant conserve malgré tout le verrou et
    		// l'autre thread devra attendre qu'il soit libéré pour continuer
    		// (via wait() ou en sortant du bloc synchronized)
    		lock.notify();
     
    	}
    Ce second thread peut prendre le verrou puisque le premier l'a libéré (via wait()), et il utilise notify() pour réveiller le premier thread. Mais pour sortir du wait ce dernier doit d'abord récupérer le verrou (toujours maintenu par le second thread tant qu'il ne sort pas du bloc synhronized).


    Plus de détail :



    Maintenant il faut bien voir que wait()/notify() ne sont que des instructions basiques de synchronisation, et qu'avec Java 5.0 on pourrait choisir de se tourner vers les packages java.util.concurrent, java.util.concurrent.atomic et java.util.concurrent.locks qui propose des mécanismes bien plus évolués

    a++

  3. #3
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    donc si j'ai bien compris wait() permet d'endormir un thread afin de liberer un verrou et pouvoir passer la main a un autre thread qui attendait la liberation du verrou.

    notify() permet de reveiller un thread endormi qui pourra etre actif des que le verrou sera levée.

    et notifyAll() fait la meme chose que notify() mais sur tous les threads endormi c'est ca ?

    merci pour ton aide adiGuba.
    "La seule chose dont je sois certain, c'est que je doute"
    j'ai cassé ma boule de cristal veuillez être clair et précis dans vos propos
    compilateur - 1 nayah - 0
    PS : je suis un

  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
    Oui c'est bien cela !

    Mais il y a quelques pièges à éviter :
    • Le lock doit être la même référence pour les deux threads : si chacun utilise le sien il ne "communiqueront" pas.
    • Il faut faire attention à l'ordonnancement : ce n'est pas parce qu'un thread est lancé en premier qu'il s'exécutera forcément avant dans tous les cas. Le problème vient lorsque le notify() est exécuté avant le wait() : le premier thread ne sera pas réveillé puisqu'il ne dort pas, mais s'endormira lorsqu'il rentrera dans le wait...

      En général il faut utiliser un booléen pour vérifier si le notify() a été appelé ou pas :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	synchronized (lock) {
    		if (!notified) {
    			lock.wait();
    		}
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	synchronized (lock) {
    		lock.notify();
    		notified = true;
    	}

    a++

  5. #5
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    ok je pense avoir compris merci pour tout adiGuba.
    "La seule chose dont je sois certain, c'est que je doute"
    j'ai cassé ma boule de cristal veuillez être clair et précis dans vos propos
    compilateur - 1 nayah - 0
    PS : je suis un

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    Est-il possible de lancer ce notify ailleurs que dans un autre thread ?

    Par exemple dans une méthode appelée dans le run avant le wait (dans mon exemple maMethode). Ou bien est-ce que la méthode ne fera pas son traitement du fait du wait?

    Ce qui donnerai l'exemple suivant :

    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
     
    public class monThread extends Thread {
    	int[] monTableau;
    	ArrayList<Integer> suivantsDe0 = new ArrayList<Integer>();
     
    	public void run() {
     
    		while(!isInterrupted())
    		{
    			if(monTableau[0] == 0){
    				maMethode();
    				try{
    					wait();
    				} catch(InterruptedException e){}
    			}
    			else{
    				for(int i=0; i<monTableau.length-1 ; i++)
    					monTableau[i] = monTableau[i+1];
    				monTableau[monTableau.length] = 0;
    			}
    		}
    	}
    	private void maMethode(){
    		if(monTableau.length > 1){
    			suivantsDe0.add(monTableau[1]);
    			for(int i=0; i<monTableau.length-2 ; i++)
    				monTableau[i] = monTableau[i+2];
    			monTableau[monTableau.length-1] = 0;
    			monTableau[monTableau.length] = 0;
    		}
    		notify();
    	}
    }

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

Discussions similaires

  1. A propos de wait(), notify() et notifyAll
    Par amine_en_france dans le forum Langage
    Réponses: 2
    Dernier message: 20/09/2010, 15h27
  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. [Thread] Probleme sur wait() / notify()
    Par Jean_pierre dans le forum Concurrence et multi-thread
    Réponses: 4
    Dernier message: 30/11/2008, 09h31
  4. synchronisation wait notify
    Par storm_2000 dans le forum Langage
    Réponses: 4
    Dernier message: 23/10/2008, 23h19
  5. Synchronize, wait, notify etc...
    Par jeje99 dans le forum Langage
    Réponses: 4
    Dernier message: 06/01/2006, 11h46

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