170 lines
5.1 KiB
Java
170 lines
5.1 KiB
Java
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
// v0.1, 25/09/20 (PM)
|
|
|
|
class TamponBorné {
|
|
/*
|
|
* Pour simplifier la mise en œuvre du test, on se limite ici à un tampon
|
|
* d'entiers
|
|
*/
|
|
private int taille; // nombre de cases du tampon
|
|
private int nbOccupé = 0; // nombre d'items présents dans le tampon (vide initialement)
|
|
private int queue = 0; // queue de file (tampon circulaire), insertions
|
|
private int tête = 0; // tête de file (tampon circulaire), extractions
|
|
|
|
private int trace = 0;// utile uniquement pour faciliter le test :
|
|
// on va considérer qu'on dépose les valeurs successives de trace...
|
|
|
|
private int[] tampon;
|
|
|
|
public TamponBorné(int t) {
|
|
taille = t;
|
|
tampon = new int[taille];
|
|
}
|
|
|
|
static AtomicBoolean occupied = new AtomicBoolean(true);
|
|
|
|
synchronized public void déposer() {
|
|
|
|
while (nbOccupé >= taille && !occupied.compareAndSet(false, true)) {
|
|
try {
|
|
System.out.println("wait prod");
|
|
this.wait();
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
// dépôt
|
|
tampon[queue] = trace++; // tampon[queue] = i;
|
|
queue = (queue + 1) % taille;
|
|
nbOccupé++;
|
|
|
|
// affichage pour le test uniquement
|
|
String msg = (char) 27 + "[0;32m" + "P : " + (trace - 1);
|
|
if (nbOccupé == taille) {
|
|
msg = msg + " (PLEIN)";
|
|
} else {
|
|
msg = msg + " (" + nbOccupé + ")";
|
|
}
|
|
msg = msg + (char) 27 + "[0m";
|
|
System.out.println(msg);
|
|
|
|
TAS.occupied.set(false);
|
|
|
|
notifyAll();
|
|
System.out.println("notification");
|
|
|
|
} // déposer()
|
|
|
|
synchronized public int retirer() { // Item remove()
|
|
int i; // Item i
|
|
|
|
while (nbOccupé <= 0 && !occupied.compareAndSet(false, true)) {
|
|
try {
|
|
System.out.println("wait conso");
|
|
this.wait();
|
|
} catch (InterruptedException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
// retrait
|
|
i = tampon[tête];
|
|
tête = (tête + 1) % taille;
|
|
nbOccupé--;
|
|
|
|
// affichage pour le test uniquement
|
|
String msg = (char) 27 + "[0;31m" + "C : " + i;
|
|
if (nbOccupé == 0) {
|
|
msg = msg + " (VIDE)";
|
|
} else {
|
|
msg = msg + " (" + nbOccupé + ")";
|
|
}
|
|
msg = msg + (char) 27 + "[0m";
|
|
System.out.println(msg);
|
|
|
|
TAS.occupied.set(false);
|
|
|
|
notifyAll();
|
|
System.out.println("notification");
|
|
|
|
return i;
|
|
} // retirer
|
|
} // TamponBorné
|
|
|
|
/* ---------- inutile de modifier ce qui suit ---------- */
|
|
|
|
class Producteur implements Runnable {
|
|
private TamponBorné tampon;
|
|
|
|
public Producteur(TamponBorné t) {
|
|
tampon = t;
|
|
}
|
|
|
|
public void run() {
|
|
try {
|
|
Thread.sleep(10); // pour le test : initialement, les consommateurs trouveront tous un tampon vide
|
|
for (int i = 0; i < 25; i++) {
|
|
// possible de trouver des producteurs bloqués à la fin, selon le nb de
|
|
// consommateurs
|
|
tampon.déposer();
|
|
Thread.sleep(2 * i); // producteurs ralentissent un peu
|
|
}
|
|
} catch (InterruptedException e) {
|
|
System.out.println("interrompu");
|
|
}
|
|
}
|
|
}
|
|
|
|
class Consommateur implements Runnable {
|
|
private TamponBorné tampon;
|
|
private int identité;
|
|
|
|
public Consommateur(TamponBorné t) {
|
|
tampon = t;
|
|
}
|
|
|
|
public void run() {
|
|
int res;
|
|
for (int i = 0; i < 25; i++) {
|
|
// possible de trouver des consommateurs bloqués à la fin, selon le nb de
|
|
// producteurs
|
|
res = tampon.retirer();
|
|
try {
|
|
Thread.sleep(10 * i); // consommateurs ralentissent davantage
|
|
} catch (InterruptedException e) {
|
|
System.out.println("interrompu");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ProdConso {
|
|
public static void main(String[] args) {
|
|
int nbProd = 5;
|
|
int nbConso = 10;
|
|
int tailleTampon = 10;
|
|
// aucun blindage : on suppose que les valeurs de paramètres fournies sont
|
|
// raisonnables
|
|
if (args.length != 3) {
|
|
System.out.println("java ProdConso <nbProd> <nbConso> <nbCases>");
|
|
System.out.println("-> choix par défaut : " + nbProd + "/" + nbConso + "/" + tailleTampon);
|
|
} else {
|
|
nbProd = Integer.parseInt(args[0]);
|
|
nbConso = Integer.parseInt(args[1]);
|
|
tailleTampon = Integer.parseInt(args[2]);
|
|
}
|
|
System.out.println("nbProd (arg1) : " + nbProd + " /nbConso (arg2) : " + nbConso + " /nbCases) (arg3) : "
|
|
+ tailleTampon + "\n");
|
|
TamponBorné t = new TamponBorné(tailleTampon);
|
|
for (int i = 0; i < nbProd; i++) {
|
|
new Thread(new Producteur(t)).start();
|
|
}
|
|
for (int i = 0; i < nbConso; i++) {
|
|
new Thread(new Consommateur(t)).start();
|
|
}
|
|
// ajouter éventuellement un thread pour gérer l'arrêt et une prise de cliché
|
|
// finale
|
|
}
|
|
} |