title: Two Class Synchronization
body: <p>I have 4 classes: Main, Producer, Consumer, and Buffer. The buffer class contains the implementation for a circular array (assume it works). The producer class adds to the buffer array and the consumer class removes from the buffer array. The Main class creates a thread for producer and for consumer. </p>
  
  <p>Inside the producer class, if the buffer is not full, it adds to it. If it is full, it waits until consumer removes something from the array. </p>
  
  <p>Inside the Consumer class, if the buffer is not empty, it removes an item from it. If it is empty, it waits until producer adds something to the buffer.</p>
  
  <p>The problem I'm having is that producer will add items to the array, but each time it notifies the consumer that it has added to the buffer, the consumer stays in the waiting state. It never continues with the rest of the code.</p>
  
  <pre><code>// Main.java
  Buffer buffer = new Buffer(5); // creates a circular array of length 5.
  
  // 10 is total number of items to be added
  Producer p = new Producer(buffer, 10); // uses random number generator for values 
  Consumer c = new Consumer(buffer, 10);
  
  p.start();
  c.start();
  
  p.join();
  c.join();
  </code></pre>
  
  <pre><code>public class Producer extends Thread {
  
      ...
  
      public void run() { 
          ...
          while(true) {
              synchronized(this) {
                  try {
                      while(buffer.isFull()) wait(); 
                      ...
                      buffer.insert(val);
                      notify();
                      ... // other stuff that eventually breaks the loop
                  } catch(InterruptedException e) {}
              }
          }
      }
  }
  </code></pre>
  
  <pre><code>public class Consumer extends Thread {
  
      ...
  
      public void run() {
          while(true) {
              synchronized(this) {
                  try {
                      while(buffer.isEmpty()) wait(); // its stuck here
                      ...
                      buffer.remove();
                      notify();
                      ... // other stuff that eventually breaks the loop
                  } catch (InterruptedException e) {}
              }
          }
      }
  }
  
  </code></pre>
  
  <pre><code>// Inside Buffer.java
  
  public void insert(int n) {
      ...
      buffer[front] = n;
      front++;
      size++;
  }
  
  public int remove() {
      ...
      temp = buffer[rear] = -1;
      rear--;
      size--;
      return temp;
  } 
  </code></pre>
  
  <p>In producer, there is a print statement that prints 5 values that were added to the buffer (max size of buffer) but then nothing happens after that. Producer adds the values to the array and then enters the waiting state, but Consumer doesn't do anything since its still remains in the waiting state.  </p>
  
  <p>I can't figure out why Consumer doesn't continue despite Producer executing notify each time it adds something to the buffer.</p>