/*
    PC.java, Loesung
    Betriebssysteme Theorie, FOM, Hans-Georg Esser, WS 2011/12
    Producer-Consumer-Problem, Java, Monitore
    Quelle: http://www.csc.villanova.edu/~mdamian/threads/javamonitors.html
*/

public class PC
{
  public static void main(String [] args) {
	  Buffer b = new Buffer(4);
	  Producer p1 = new Producer(b,'A');
	  Producer p2 = new Producer(b,'K');
	  Producer p3 = new Producer(b,'U');
	  Consumer c  = new Consumer(b);

	  p1.start();
	  p2.start();
	  p3.start();
	  c.start();;
  }
}

class Buffer {
   private char [] buffer;
   private int count = 0, in = 0, out = 0;

   Buffer(int size)
   {
      buffer = new char[size];
   }
 
   public synchronized void Put(char c) {
	   while(count == buffer.length) {
		   try { wait(); }
		   catch (InterruptedException e) {}
		   finally {}
	   };
	   // System.out.println("Producing " + c + " ...");
	   buffer[in] = c; 
	   in = (in + 1) % buffer.length;
	   count++;
	   notify();
   }
    
   public synchronized char Get() {
	   while (count == 0) {
		   try { wait(); }
		   catch (InterruptedException e) {}
		   finally {}
	   };
       char c = buffer[out]; 
       out = (out + 1) % buffer.length;
       count--;
       // System.out.println("Consuming " + c + " ...");
       System.out.print(c);
       notify();  
       return c;
   }
}
     

class Producer extends Thread {
	private Buffer buffer;
	private char start;
	Producer(Buffer b, char c) { 
		buffer = b; 
		start = c;
	}

	public void run() {
		for(int i = 0; i < 10; i++) {
			buffer.Put((char)(start+ i%26 )); }
	}
}

class Consumer extends Thread {
   private Buffer buffer;
   
   Consumer(Buffer b) { buffer = b; }
   public void run() {
     for(int i = 0; i < 30; i++) {
        buffer.Get(); }
	   System.out.println();
   }
}   



