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.