edutecnica

Esercizio 3                     

Un processo produttore genera in modo casuale (anche con ripetizioni) numeri da 1 a 10 (inclusi) e li memorizza in un buffer che può contenere un solo numero alla volta.

Due processi consumatori concorrenti tentano di acquisire tali numeri soltanto dopo la loro produzione.
Uno dei due consumatori tenta di acquisire solo numeri da 1 a 5, l'altro solo numeri che vanno da 6 a 10 .


Si usa la classe buffer come monitor, i metodi put() e get() della stessa classe vengono usati, rispettivamente dal produttore p e dai consumatori c1 e c2.

Come si nota dall'output, il programma andrebbe ulteriormente corretto in modo che nel buffer non venga allocato un nuovo valore prodotto prima che il precedente non sia stato consumato (da c1 o da c2).

public class pc{
public static void main(String[] args) {
Buffer b = new Buffer();
Consumatore c1 = new Consumatore(b,"C1");
Consumatore c2 = new Consumatore(b,"C2");
Produttore p = new Produttore(b);
c1.start(); c2.start(); p.start();
try{Thread.sleep(5000);
}catch(InterruptedException e){e.printStackTrace();}
p.stop(); c1.stop();c2.stop();
} //fine main
} //fine classe pc
class Buffer { //monitor
protected boolean pronto = false;
private int dato;
public synchronized void put(int x) {
while(pronto) {
   try {wait();
   }catch(InterruptedException e) {e.printStackTrace();}
} //fine while
dato = x;
pronto = true;
notifyAll();
} //fine synchronized put()
public synchronized int get() {
while(!pronto) {
   try {wait();
   }catch(InterruptedException e) {e.printStackTrace();}
} //fine while
pronto = false;
notifyAll();
return dato;
} //fine synchronized get()
} //fine classe buffer
class Produttore extends Thread {
private Buffer buffer;
private int h;
public Produttore(Buffer b) {buffer = b;}//costruttore
public void run() {
for(int i = 0; i < 10; i++) {
   synchronized(buffer){
         h=(1 + (int) (Math.random() * 10));
         buffer.put(h);
         System.out.println("prodotto:"+h);
   }//fine synchronized
}//fine for
}//fine run
}//fine classe produttore
class Consumatore extends Thread {
private Buffer buffer;
private int x;
private String nome;
public Consumatore(Buffer b, String s) {buffer = b;nome=s;}//costruttore
public void run() {
while(true) {
synchronized(buffer){
  x = buffer.get();
  //C1 consuma solo numeri da 1 a 5
  //C2 consuma solo numeri da 6 a 10

  if(this.nome=="C1" && x < 6 ){System.out.println(nome+"- consuma:"+x);}
  if(this.nome=="C2" && x > 5){System.out.println(nome+"- consuma:"+x);}
}//fine synchronized
}//fine while
}//fine run
}//fine classe Consumatore

L'output dovrebbe apparire nel seguente modo:
prodotto:7
C2- consuma:7
prodotto:2
C1- consuma:2
prodotto:7
C2- consuma:7
prodotto:1
C1- consuma:1
prodotto:5
prodotto:8
C2- consuma:8
prodotto:8
prodotto:1
prodotto:9
prodotto:7
C2- consuma:7