package thread;

public class Queues {
  private static final int queue_size = 10;
  private Object[] queue =
      new Object[queue_size];

  private int head = 0;
  private int tail = 0;

  synchronized public void
      enqueue(Object item) {
    ++head;
    int i = head % queue_size;
    queue[i] = item;
    this.notify();
  }

  synchronized public Object dequeue() {
    try {
      while (head == tail) {
        this.wait();
      }
    } catch (InterruptedException e) {
      return null;
    }
    return queue[++tail % queue_size];
  }

  public static void main(String args[]) {
    Queues q
        = new Queues();
    q.enqueue(q);
    q.enqueue(q);
    System.out.println(q);
    System.out.println(q.dequeue());

  }
}

class Consumer implements Runnable {
  Queues q;

  Consumer(Queues _q) {
    q = _q;
  }

  public void run() {
    while (true) {
      System.out.println(
          (String) q.dequeue());
    }
  }
}

class Producer {

  public static void main(String args[]) {
    Queues q =
        new Queues();
    Thread ct = new Thread(new Consumer(q));
    Producer p = new Producer();
    ct.start();
    q.enqueue("This is my first entry");
    q.enqueue("This is my second entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
    q.enqueue("This is my third entry");
  }
}