Filter Streams   «Prev  Next»

Lesson 9Streaming data between threads
ObjectiveLearn how to connect Threads.

Communicating Between Threads with Piped Streams

The java.io.PipedInputStream class and java.io.PipedOutputStream class provide a convenient means to move streaming data from one thread to another. Output from one thread becomes input for the other thread. Piped streams are normally created in pairs. The piped output stream becomes the underlying source for the piped input stream.
To use the piped output stream as the underlaying source for the piped input stream, you might write something like this:

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

Simple Example

This simple example is a little deceptive because these lines of code will normally be in different methods, and perhaps even different classes. Some mechanism must be established to pass a reference to the PipedOutputStream into the thread that handles the PipedInputStream. Or you can create them in the same thread; then pass a reference to the connected stream into a separate thread.
Alternatively, you can reverse this:

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


Piped Input Stream
Figure 5.9: Data moving between threads with piped streams

Or you can create them both unconnected, then use one or the other's connect() method to link them:
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos);

Otherwise, these classes just have the usual
  1. read(),
  2. write(),
  3. flush(),
  4. close(), and
  5. available()
methods like all stream classes.

Example of a Java program using PipedOutputStream to send data to PipedInputStream

Here is an example of a Java program that uses a PipedOutputStream to send data to a PipedInputStream. This program creates two threads: one to write data to the PipedOutputStream, and another to read data from the PipedInputStream.

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeExample {
   public static void main(String[] args) {
       try {
           // Create the PipedOutputStream and PipedInputStream
           final PipedOutputStream output = new PipedOutputStream();
           final PipedInputStream input = new PipedInputStream(output);

           // Create a thread to write data to the PipedOutputStream
           Thread writer = new Thread(() -> {
               try {
                   output.write("Hello, World!".getBytes());
                   output.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           });

           // Create a thread to read data from the PipedInputStream
           Thread reader = new Thread(() -> {
               try {
                   int data = input.read();
                   while (data != -1) {
                       System.out.print((char) data);
                       data = input.read();
                   }
                   input.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           });
           // Start both threads
           writer.start();
           reader.start();
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}
The program starts by creating a PipedOutputStream and a PipedInputStream, connecting them together. Then it creates two threads, one that writes "Hello, World!" to the PipedOutputStream, and another that reads data from the PipedInputStream and prints it to the console. The program starts both threads, which run concurrently and share the data between them via the pipe.