A lezione abbiamo visto la realizzazione del sistema con una coda programmata da noi:

Adesso vogliamo modificare la coda in modo che sia bloccante per letture da coda vuota e scritture su coda piena.

Esercizio 1

Realizzare un sistema con un produttore e un consumatore

public class ProdCons {
	final int BUFFSIZE=4;
	void exec(){
		Coda cella=new Coda(4);
		new Produttore("Prod1", cella).start();
		new Consumatore("Cons1", cella).start();
		new Produttore("Prod2", cella).start();
		new Consumatore("Cons2", cella).start();
	}

	public static void main(String[] args) {
		new ProdCons().exec();
	}
}
import java.util.concurrent.*;

public class Produttore extends Thread {
	Coda buffer;
	public Produttore(String s, Coda c){
		super(s);
		this.buffer=c;
	}
	public void run(){
		int i=0;
		for(;;){
			try {
				Thread.sleep(ThreadLocalRandom.current().
						nextInt(10, 100));
			} catch (InterruptedException e) {  }
			buffer.setItem(i++);
		}
	}
}
import java.util.concurrent.*;

public class Consumatore extends Thread {
	Coda buffer;
	int v;
	public Consumatore(String s, Coda c){
		super(s);
		this.buffer=c;
	}
	public void run(){
		for(;;){
			v=buffer.getItem();
			try {
				Thread.sleep(ThreadLocalRandom.current().
						nextInt(10, 100));
			} catch (InterruptedException e) {  }
		}
	}
}
import java.util.concurrent.Semaphore;

public class Coda {
	static int BUFFERSIZE;
	private int numItems = 0;
	private int[] valori;
	private int first, last; // last is the index of the
	// most recently inserted item
	Semaphore mutex, full, empty;

	Coda(int size){
		BUFFERSIZE=size;
		mutex = new Semaphore(1);
		full = new Semaphore(0);
		empty = new Semaphore(BUFFERSIZE);
		first = 0; last = 0;
		valori = new int[BUFFERSIZE];
	}

	void printWithName(String s, int v) {
		System.out.println(Thread.currentThread().getName()+s+v+"["+numItems+"]");		
	}

	public int getItem(){
		int tmp;
		try{
			full.acquire();
		} catch(InterruptedException e) {}
		try{
			mutex.acquire();
		} catch(InterruptedException e) {}
		numItems--;
		tmp=valori[first];
		first=(first+1)%BUFFERSIZE;
		printWithName(" letto ", tmp);
		mutex.release();
		empty.release();
		return tmp;
	}

	public void setItem(int v) {
		try{
			empty.acquire();
		} catch(InterruptedException e) {}
		try{
			mutex.acquire();
		} catch(InterruptedException e) {}

		valori[last]=v;
		last=(last+1)%BUFFERSIZE;
		numItems++;
		printWithName(" scritto ", v);
		mutex.release();
		full.release();
	}

	public int getCurrentSize(){
		return numItems;
	}
}

Esercizio 2

Realizzare un sistema con un produttore e un consumatore

import java.util.concurrent.*;

public class Produttore extends Thread {
	Coda buffer;
	public Produttore(String s, Coda c){
		super(s);
		this.buffer=c;
	}
	public void run(){
		int i=0;
		for(;;){
			try {
				Thread.sleep(ThreadLocalRandom.current().
						nextInt(10, 100));
			} catch (InterruptedException e) {  }
			buffer.setItem(i++);
		}
	}
}
import java.util.concurrent.*;

public class Consumatore extends Thread {
	Coda buffer;
	int v;
	public Consumatore(String s, Coda c){
		super(s);
		this.buffer=c;
	}
	public void run(){
		for(;;){
			v=buffer.getItem();
			try {
				Thread.sleep(ThreadLocalRandom.current().
						nextInt(10, 100));
			} catch (InterruptedException e) {  }
		}
	}
}
import java.util.concurrent.Semaphore;

public class Coda {
	static int BUFFERSIZE;
	private int numItems = 0;
	private int[] valori;
	private int first, last; // last is the index of the
	// most recently inserted item
	Coda(int size){
		BUFFERSIZE=size;
		first=0; last=0;
		valori=new int[BUFFERSIZE];
	}
	void printWithName(String s, int v) {
		System.out.println(Thread.currentThread().getName()+s+v+"["+numItems+"]");		
	}
	public synchronized int getItem(){
		int tmp;
		while(numItems==0) {
			try {
				wait();
			} catch (InterruptedException e) { }
		}
		numItems--;
		tmp=valori[first];
		first=(first+1)%BUFFERSIZE;
		printWithName(" letto ", tmp);
		notifyAll();
		return tmp;
	}

	public synchronized void setItem(int v) {
		while(numItems==BUFFERSIZE) {
			try {
				wait();
			} catch (InterruptedException e) { }
		}
		valori[last]=v;
		last=(last+1)%BUFFERSIZE;
		numItems++;
		printWithName(" scritto ", v);
		notifyAll();
	}

	public int getCurrentSize(){
		return numItems;
	}
}
public class ProdCons {
	final int BUFFSIZE=4;
	void exec(){
		Coda cella=new Coda(4);
		new Produttore("Prod1", cella).start();
		new Consumatore("Cons1", cella).start();
		new Produttore("Prod2", cella).start();
		new Consumatore("Cons2", cella).start();
	}
	public static void main(String[] args) {
		new ProdCons().exec();
	}
}