Se coordonner grâce aux méthodes <tt>wait</tt> et <tt>notify</tt> : solution où la coordination est gérée par les participants                  

Se coordonner pour l'utilisation d'une ressource grâce aux méthodes wait et notify : solution où la coordination est gérée par les participants

     

Le problème est le même que celui de l'exemple précédent, la facçon de la traiter diffère. . Aucun mécanisme de coordination (par les méthodes wait et notify) n'est prévu par la boîte aux lettres pour maintenir la contrainte de contenir au plus une lettre ; les producteurs et les consommateurs doivent se charger de ce bon fonctionnement. C'est ce qui est fait dans le programme ci-dessous : lorsqu'on définit la méthode run du producteur (resp. consommateur), on impose que celui-ci attende que la boîte soit vide (resp. pleine) pour déposer (resp. retirer) sa lettre.

import java.util.Random;

class BoiteAuxLettresBis
{
  boolean plein = false;
  String lettre;

  void deposer(String lettre)
    {
      this.lettre = lettre;
      System.out.println("depot de : " + lettre);
      plein = true;
    }

  String retirer(String nomConso)
    {
      plein = false;
      System.out.println(nomConso + " lit : " + lettre);
      return lettre;
    }
}

class ProducteurBis extends Thread
{
  BoiteAuxLettresBis boite;
  String nom;      
  Random alea;
  
  ProducteurBis(BoiteAuxLettresBis boite, String nom, Random alea)
    {
      this.boite = boite;
      this.nom = nom;
      this.alea = alea;
    }
  
  public void run() 
    {
      try
	{
	  for (int i = 0;i < ProdCons.TOTAL;i++)
	    {
	      sleep(Math.abs(alea.nextInt())%1000);
	      synchronized(boite)
		{
		  while(boite.plein)
		    {
		      boite.wait();
		    }
		  boite.deposer(nom +", lettre "+(i + 1));
		  boite.notifyAll();
		}
	    }
	}
      catch(InterruptedException exc) 
      {
          System.out.println("interruption");
          System.exit(1);
      }
    }
}

class ConsommateurBis extends Thread
{
  BoiteAuxLettresBis boite;
  String nom;
  String lettre;
  Random alea;

  ConsommateurBis(BoiteAuxLettresBis boite, String nom,  Random alea)
    {
      this.boite = boite;
      this.nom = nom;
      this.alea = alea;
    }

  public void run()
    {
      try
	{
	  for (int i = 0;i < ProdCons.TOTAL; i++)
	    {
	      sleep(Math.abs(alea.nextInt())%1000);
	      synchronized(boite)
		{ 
		  while(!boite.plein)
		    {
		      boite.wait();
		    }
		  lettre=boite.retirer(nom);
		  boite.notifyAll();
		}
	    }
	}
      catch(InterruptedException exc) 
      {
         System.out.println("interruption");
      }
    }
}

class ProdConsBis 
{
  final static int TOTAL = 3;

  public static void main(String[] argv)
    {
      BoiteAuxLettresBis boite = new BoiteAuxLettresBis();
      Random alea = new Random();
      
      (new ProducteurBis(boite,"David", alea)).start();
      (new ProducteurBis(boite,"Antoine", alea)).start();
      (new ConsommateurBis(boite,"Sophie", alea)).start();
      (new ConsommateurBis(boite,"Marie", alea)).start(); 
    }
}
On a obtenu :
depot de : Antoine, lettre 1
Marie lit : Antoine, lettre 1
depot de : David, lettre 1
Sophie lit : David, lettre 1
depot de : Antoine, lettre 2
Sophie lit : Antoine, lettre 2
depot de : David, lettre 2
Marie lit : David, lettre 2
depot de : David, lettre 3
Marie lit : David, lettre 3
depot de : Antoine, lettre 3
Sophie lit : Antoine, lettre 3

Vous pouvez récupérer le programme d'exemple.