// file: Pipes.java

import java.io.*;

/** Producer-consumer example with pipes.
 * @author Jaanus Poial
 * @version 0.4
 * @since 1.2
 */
public class Pipes {

   /** Main method */
   public static void main (String[] param) {
      try {
         PipedOutputStream writer = new PipedOutputStream();
         PipedInputStream  reader = new PipedInputStream();
         Producer producerthread = new Producer (writer);
         Consumer consumerthread = new Consumer (reader);
         writer.connect (reader); // symmetry (other options exist)
         producerthread.start();
         consumerthread.start();
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }
   } // main

} // Pipes 


/** Producer class. */
class Producer extends Thread {

   /** where to send produced items */
   PipedOutputStream stream;

   /** constructor */
   Producer (PipedOutputStream p) {
      stream = p;
   }

   /** thread content */
   public void run() {
      System.out.println ("Producer started... ");
      try {
         for (int i = 0; i < 9; i++) {
            int r = (int)(Math.random()*256);
            stream.write (r); // producing
            System.out.println (i + ". produced: " + r);
            try {
               sleep ((int)(Math.random()*1000));
            } catch (InterruptedException e) {
            }
         }
         stream.close(); // reader can continue reading
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }
      System.out.println ("Producer finished...");
   } // run

} // Producer


/** Consumer class. */
class Consumer extends Thread {

   /** where to get items to consume */
   PipedInputStream stream;

   /** constructor */
   Consumer (PipedInputStream p) {
      stream = p;
   }

   /** consumer thread content */
   public void run() {
      System.out.println ("Consumer started... ");
      try {
         int i = 0;
         int r = -1;
         while ((r = stream.read()) != -1) {
            System.out.println (i++ + ". consumed: " + r);
            try {
               sleep ((int)(Math.random()*1000));
            } catch (InterruptedException e) {
            }
         }
         stream.close(); // reader closes finally
      }
      catch (IOException e) {
         System.out.println ("Input/output error: " + e);
      }
      System.out.println ("Consumer finished...");
   } // run

} // Consumer

// end of file

