package com.tutego.insel.thread;

import java.util.LinkedList;
import java.util.Queue;

class Producer extends Thread
{
  private static final int MAXQUEUE = 13;

  private Queue<String> messages = new LinkedList<String>();

  @Override
  public void run()
  {
    try
    {
      while ( true )
      {
        produce();
        sleep( (int)(Math.random()*1000) );
      }
    } catch ( InterruptedException e ) { e.printStackTrace(); }
  }

  public synchronized void produce()
    throws InterruptedException
  {
    while ( messages.size() == MAXQUEUE )
      wait();

    messages.add( new java.util.Date().toString() );
    notifyAll();    // oder notify();
  }

  // vom Verbraucher aufgerufen
  public synchronized String consume() throws InterruptedException
  {
    while ( messages.size() == 0 )
      wait();
    
    notifyAll();

    return messages.poll();
  }
}

class Consumer extends Thread
{
  Producer producer;
  String   name;
  
  Consumer( String name, Producer producer )
  {
    this.producer = producer;
    this.name = name;
  }

  @Override
  public void run()
  {
    try
    {
      while ( true )
      {
        String info = producer.consume();

        System.out.println( name + " holt Nachricht: "+ info );

        Thread.sleep( (int)(Math.random()*1000) );
      }
    } catch ( InterruptedException e ) { e.printStackTrace(); }
  }
}

public class ProducerConsumerDemoWaitNotify
{
  public static void main( String[] args )
  {
    Producer producer = new Producer();
    producer.start();
    
    new Consumer( "Eins", producer ).start();
    new Consumer( "Zwei", producer ).start();
    new Consumer( "Drei", producer ).start();
  }
}
