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 :

[Débutant] Synchronisation - wait() et notifyAll()


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut [Débutant] Synchronisation - wait() et notifyAll()
    Bonjour à tous !

    Je débute en JAVA et j'ai un petit problème pour la synchronisation :

    Un maçon et un électricien doivent réaliser des travaux. Ces deux classes héritent d'une classe "corps de métier" qui contient les données de synchronisation. L'électricien commence ses travaux lorsque le maçon a fini les siens.

    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 CorpsMetier extends Thread {
    	public synchronized void attendreFinTravauxPrecedentCorpsMetier () {
    		try {
    			wait();
    		}
    		catch(InterruptedException e){}
    	}
     
    	public synchronized void finTravaux(){
    		notifyAll();
    	}
    }
     
    public class Macon extends CorpsMetier {	
    	public void run() {
    		try {
    			System.out.println("Le maçon travaille");
    			sleep(5000); // Le maçon fait son travail
    		} catch (InterruptedException e) {}
     
    		finTravaux();
    	}
    }
     
    public class Electricien extends CorpsMetier {	
    	public void run() {
    		attendreFinTravauxPrecedentCorpsMetier();
     
    		try {
    			System.out.println("L'électricien travaille");
    			sleep(5000); // L'électricien fait son travail
    		} catch (InterruptedException e) {}
     
    		finTravaux();
    	}
    }

    DANS LE MAIN :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Macon macon = new Macon();
    Electricien electricien = new Electricien();
     
    macon.start();
    electricien.start();

    Mon problème est que l'électricien reste bloqué sur le wait() et par conséquent ne fait jamais son travail. Le problème vient-il du fait que je n'utilise pas le même objet ? Je veux dire que le wait() de l'électricien attend un notifyAll() d'un autre electricien et non pas d'un maçon comme dans mon code ? Quelles solutions ?


    Merci d'avance.
    Matth.

  2. #2
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut
    Help ! ^^

  3. #3
    Membre chevronné Avatar de T`lash
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Saint-Pierre-Et-Miq.

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Septembre 2007
    Messages : 381
    Par défaut
    À la base tu as déjà un problème de conception puisque tu mélanges les ouvriers et les travaux qu'ils doivent effectuer.
    Ce n'est pas une bonne approche objet.
    Jamais tes classes corps de métier ne devraient avoir à étendre la classe Thread.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class Oeuvre {
      //propriétés et méthodes d'une oeuvre du BTP.
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public class CorpsMetier {
    	//propriétés et méthodes communes
    	private Oeuvre travailEnCours;
    }
    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 Macon extends CorpsMetier {	
    	public void construire(Oeuvre oeuvre) {
    		this.travailEnCours = oeuvre;
    		new Thread(){
    			@Override public void run() {
    				synchronized (this.travailEnCours) {
    					try {
    						System.out.println("Le maçon travaille");
    						// Le maçon fait son travail
    						monterLesMurs(oeuvre);
    						construireLeToit(oeuvre);
    					} catch (InterruptedException e) {}
    					this.travailEnCours.notifyAll();
    				}
    			}
    		}.start();
    	}
     
    	private void monterLesMurs(){
    		sleep(2500);
    	}
     
    	private void construireLeToit(){
    		sleep(2500);
    	}
    }
    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 Electricien extends CorpsMetier {		
    	public void creerReseauElectrique(Oeuvre oeuvre) {
    		this.travailEnCours = oeuvre;
    		new Thread(){
    			@Override public void run() {
    				synchronized (this.travailEnCours) {
    					try {
    						System.out.println("L'électricien travaille");
    						// L'électricien fait son travail
    						cablerLeBatiment(oeuvre);
    						relierLeTableauElectrique(oeuvre);
    					} catch (InterruptedException e) {}
    					this.travailEnCours.notifyAll();
    				}
    			}
    		}.start();
    	}
     
    	private void cablerLeBatiment(){
    		sleep(2500);
    	}
     
    	private void relierLeTableauElectrique(){
    		sleep(2500);
    	}
    }

    Et dans ta classe principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public void main(String[] args) {
    	Oeuvre uneMaisonAConstruire = new Oeuvre();
     
    	Macon macon = new Macon();
    	Electricien electricien = new Electricien();
     
    	macon.construire(uneMaisonAConstruire);
    	electricien.creerReseauElectrique(uneMaisonAConstruire);
    }

    Comme ça le verrou est posé sur l'œuvre à réaliser et les Threads correspondent à des tâches effectives.

    Par contre, dans une application il faudra en plus que tu prévois le cas où un ouvrier soit demandé sur deux chantiers différents.

    Dans ce cas il te suffit de poser en plus un verrou sur l'ouvrier lorsqu'il effectue une tâche. Sans oublier de le libérer ensuite par la notification.

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut
    Merci beaucoup T`lash, c'est le coup de pouce dont j'avais besoin !!!
    Cependant cette syntaxe me génère une erreur au niveau des accolades lors de la création du Thread (new Thread(){ ... }) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    new Thread(){
    	synchronized (oeuvre) {
    		try {
    			System.out.println("L'électricien travaille");
    			// L'électricien fait son travail
    			cablerLeBatiment(oeuvre);
    			relierLeTableauElectrique(oeuvre);
    		} catch (InterruptedException e) {}
    		oeuvre.notifyAll();
    	}
    }.start();

  5. #5
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354

  6. #6
    Membre chevronné Avatar de T`lash
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Saint-Pierre-Et-Miq.

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Septembre 2007
    Messages : 381
    Par défaut
    C'est tout simplement parce que j'ai fait une erreur dans le code que je t'ai donné.

    Le code dans le Thread est en fait le corps de la méthode run.

    Je vais corriger mon post.

    Edit : c'est fait

Discussions similaires

  1. Problème wait et notifyAll
    Par Linquisiteur dans le forum Débuter avec Java
    Réponses: 12
    Dernier message: 24/10/2014, 21h34
  2. Problème wait() et notifyAll()
    Par Liiinz dans le forum Agents de placement/Fenêtres
    Réponses: 1
    Dernier message: 12/09/2011, 20h28
  3. synchronisation wait notify
    Par storm_2000 dans le forum Langage
    Réponses: 4
    Dernier message: 23/10/2008, 23h19
  4. [wait][notifyAll]
    Par floanne dans le forum Langage
    Réponses: 2
    Dernier message: 14/04/2006, 22h44
  5. [débutant][Thread] wait et NotifyAll
    Par norkius dans le forum Concurrence et multi-thread
    Réponses: 2
    Dernier message: 14/03/2005, 15h28

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