A Producer/Consumer Example
Home ] Up ] Producer/Consumer Relationships ] Conditions ] [ A Producer/Consumer Example ]

 

 

Here's an example of a Producer and a Consumer class, with a SharedBuffer class that provides the necessary coordination between the two threads:

package threads;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 *  This is a Producer thread that supplies strings
 *  to a Consumer thread.  It reads a line from System.in
 *  and passes it to the Consumer through a SharedBuffer,
 *  until the end of stream occurs.
 */
public class Producer extends Thread
{
  public static void main(String[] args)
  {
    // Create a shared buffer
    SharedBuffer buffer = new SharedBuffer();
    // Create and start a consumer thread
    Consumer consumer = new Consumer(buffer);
    consumer.start();
    // Create and start a Producer thread
    Producer producer = new Producer(buffer);
    producer.start();
  }
  
  Producer(SharedBuffer buffer)
  {
    super("Producer");
    m_buffer = buffer;
  }
  
  public void run()
  {
    // Connect up to System.in
    BufferedReader reader = new BufferedReader(
      new InputStreamReader(System.in)
      );
    
    try
    {
      // Loop, asking for input from the user until EOF
      while (true)
      {
        String line = reader.readLine();
        if (line == null)
          break;      // End of input
        m_buffer.putData(line);
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    
    System.out.println("Done with input: Signalling to Consumer");
    m_buffer.putData(null);
  }
  
  /// Private data ///
  private SharedBuffer m_buffer;
}

/**
 *  This is a Consumer thread that waits for input from
 *  the Producer, supplied through a SharedBuffer.  It
 *  accepts the string passed, reverses it, and prints out
 *  the result.  When it encounters a null string, the thread
 *  exits.
 */
class Consumer extends Thread
{
  Consumer(SharedBuffer buffer)
  {
    super("Consumer");
    m_buffer = buffer;
  }
  
  public void run()
  {
    while (true)
    {
      String line = m_buffer.getData();
      if (line == null)
        break;
      // Reverse the line and print it out
      line = reverse(line);
      System.out.println(line);
    }
    
    System.out.println("Consumer thread exiting...");
  }
  
  private String reverse(String string)
  {
    StringBuffer buffer = new StringBuffer(string);
    return buffer.reverse().toString();
  }
  
  //// Private data ////
  private SharedBuffer m_buffer;
}

/**
 *  This is a SharedBuffer class to which the Producer puts
 *  data, and from which the Consumer retrieves it.
 *  It contains the necessary thread coordination code to
 *  ensure that the Producer and Consumer work together properly.
 */
class SharedBuffer
{
  static final int RESOURCE_LIMIT = 10;
  
  boolean isFull()
  {
    return m_data.size() > RESOURCE_LIMIT;
  }
  
  boolean isEmpty()
  {
    return m_data.size() <= 0;
  }
  
  synchronized void putData(String s)
  {
    while ( isFull() )  // Wait until there's room
    {
      try
      {
        wait();
      }
      catch (InterruptedException e)
      {
        // Ignore
      }
    }
    
    m_data.add(s);   // To the end of the FIFO list
    
    notify();       // Notify any waiter
  }
  
  synchronized String getData()
  {
    while ( isEmpty() ) // Wait until there's data available
    {
      try
      {
        wait();
      }
      catch (InterruptedException e)
      {
        // Ignore
      }
    }
    
    String data = (String)(m_data.get(0)); // Get first element
    if (data != null)
      m_data.remove(data);     // and remove it from the List
    
    notify();       // Notify any waiter
    
    return data;
  }
  
  //// Private data ////
  
  // A list of strings.
  private List<String> m_data = new ArrayList<String>();
  private boolean m_done = false;
}

Here's a simple example of one run of this program:

Hello!
!olleH
How are you?
?uoy era woH
Nice talking to you!
!uoy ot gniklat eciN
Goodbye
eybdooG
Done with input: Signalling to Consumer
Consumer thread exiting...
 
The page was last updated February 19, 2008