Sending Data Between Threads

   

Java™ 2 Primer Plus
By Steven Haines, Steve Potts

Table of Contents
Chapter 18.  Programming with Threads


Some program designs can benefit not only from having multiple threads, but also from having those threads send data to each other. The mechanism that is used to perform this communication is called a pipe. There are two classes that facilitate this work, the PipedOutputStream, which manages the sending of data, and the PipedInputStream, which manages the reception of data. One thread instantiates a PipedOutputStream and writes to it. The other thread instantiates a PipedInputStream and reads from it. Listing 18.11 shows how this works.

Listing 18.11 The TestPipes.java File
 /*   * TestPipes.java   *   * Created on September 27, 2002, 11:29 AM   */  package ch18;  import java.io.*;   /**   *   * @author  Stephen Potts   */  public class TestPipes  {      /** Creates a new instance of TestPipes */      public TestPipes()      {      }      public static void writeData(OutputStream os)      {          try          {              DataOutputStream out = new DataOutputStream(              new BufferedOutputStream(os));              int[] numArray =              { 1, 10, 2, 9, 3, 7, 4, 6, 5, 100, 200 };              for(int i=0; i<numArray.length; i++)              {                  out.writeInt(numArray[i]);              }              out.flush();              out.close();          }catch (IOException ioe)          {              ioe.printStackTrace();          }      }      public static void readData(InputStream is)      {          try          {              DataInputStream in = new DataInputStream(              new BufferedInputStream(is));              boolean eof = false;              while(!eof)              {                  try                  {                      int iValue = in.readInt();                      System.out.println("read value = " + iValue);                  }catch(EOFException eofe)                  {                       eof = true;                  }              }              System.out.println("End of Data");          }catch (IOException ioe)          {              ioe.printStackTrace();          }      }      public static void main(String[] args)      {          try          {              final PipedOutputStream pos=              new PipedOutputStream();              final PipedInputStream pis=              new PipedInputStream(pos);              Runnable runOutput = new Runnable()              {                  public void run()                  {                      writeData(pos);                  }              };              Thread outThread = new Thread(runOutput, "outThread");              outThread.start();              Runnable runInput = new Runnable()              {                  public void run()                  {                      readData(pis);                  }              };              Thread inThread = new Thread(runInput, "inThread");              inThread.start();          }catch (IOException ioe)          {              ioe.printStackTrace();          }      }  } 

We create one static method that writes the data. It has to be static because we are going to call it from inside an inner class.

 public static void writeData(OutputStream os) 

We take in an OutputStream object and we add the contents of an array to it.

 DataOutputStream out = new DataOutputStream(  new BufferedOutputStream(os));  int[] numArray =  { 1, 10, 2, 9, 3, 7, 4, 6, 5, 100, 200 }; 

The input method is static also. It takes an InputStream as a parameter.

 public static void readData(InputStream is) 

We create a BufferedInputStream and read from it until the stream is empty.

 DataInputStream in = new DataInputStream(  new BufferedInputStream(is)); 

We simply print the data to the console to show that it worked.

 System.out.println("read value = " + iValue); 

In the main() method, we instantiate a PipedOutputStream and a PipedInputStream. Notice that the PipedOutputStream is an input to the PipedInputStream constructor.

 final PipedOutputStream pos=  new PipedOutputStream();  final PipedInputStream pis=  new PipedInputStream(pos); 

Using the same anonymous innerclass technique that we have used earlier in this chapter, we call the writeData() method in its own thread.

 Runnable runOutput = new Runnable()  {      public void run()      {          writeData(pos);      }  };  Thread outThread = new Thread(runOutput, "outThread");  outThread.start(); 

We call the readData() method in a thread also.

 Runnable runInput = new Runnable()  {      public void run()      {          readData(pis);      }  };  Thread inThread = new Thread(runInput, "inThread");  inThread.start(); 

The output from this program is shown here.

 read value = 1  read value = 10  read value = 2  read value = 9  read value = 3  read value = 7  read value = 4  read value = 6  read value = 5  read value = 100  read value = 200  End of Data 

Notice that a PipedInputStream and a PipedOutputStream were passed into the writeData() and readData() methods, respectively. This might seem strange to you because the signatures for these methods call for OutputStream and InputStream objects. This works because OutputStream is the parent of PipedOutputStream and InputStream is the parent of PipedInputStream. By the rules of polymorphism, these upcasts are legal.


       
    Top
     



    Java 2 Primer Plus
    Java 2 Primer Plus
    ISBN: 0672324156
    EAN: 2147483647
    Year: 2001
    Pages: 332

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net