Andbin ho aggiunto all'interno dei metodi run() del Produttore e del Consumatore due blocchi synchronized, sincronizzati sull'oggetto buffer, e sembra che ora funzioni tutto bene


codice:
public class Consumatore implements Runnable {

	private Buffer<Paziente> buffer;
	private int ritardo;
	
	
	public Consumatore (Buffer<Paziente> buffer, int ritardo)
	{
		this.ritardo=ritardo;
		this.buffer=buffer;
	}
	
	public void run() {
		
		int i;
		
		for(i=0; true; i++)
		{
			synchronized(buffer)
			{
			Paziente p = buffer.preleva();
			System.out.println ("Prelevato: " + p + "\n" + buffer.getSize());
			}
			try
			{
				Thread.sleep(ritardo);
			}
			catch(InterruptedException e){}	
		}	
	}
}


codice:
public class Produttore implements Runnable{

	private Buffer<Paziente> buffer;
	private int ritardo;
	
	
	public Produttore (Buffer<Paziente> buffer, int ritardo)
	{
		this.buffer=buffer;
		this.ritardo=ritardo;
	}
	
	
	
	public void run() {
		
		int i;
		
		for(i=0; true; i++)
		{
			synchronized(buffer)
			{
			Paziente p = new Paziente("Nome " + i, "Cognome " + i);
			
			buffer.aggiungi(p);
			System.out.println("Inserito: " + p + buffer.getSize());
			}
			try
			{
				Thread.sleep(ritardo);
			}
			catch(InterruptedException e){}	
		}	
	}
}
Ho provato tutte le possibili combinazioni, velocità uguali del prod. e cons., diverse ecc..... e con qualsiasi dimensione della struttura dati, e l'output è come ci si aspettasse, quindi non ci sono più problemi di stampe di pazienti prima delle stampe dell'arrivo, e/o viceversa.

Grazie 1000 Andbin