Cambios en el JDK 1.1:
Tuberías

El ejemplo RhymingWords ilumina las clases PipedInputStream y PipedOutputStream. El JDK 1.1 introduce dos nuevas clases, PipedReader y PipedWriter, que realizan las mismas funciones que PipedInputStream y PipedOutputStream sólo que trabajan con caracteres y no con bytes. Generalmente hablando es mejor utilizar las nuevas clases de streams de caracteres. Similarmente, el uso de otros streams de este ejemplo (como FileReader) deberían cambiarse para utilizar las clases de streams de caracteres correspondientes (como FileInputStream).

También, si intentas compilar el ejemplo RhymingWords de Utilizar Streams para Implementar Tuberías utilizando el compilador del JDK 1.1, encontrarás que utiliza un API caducado. En particular, DataInputStream.readLine ha caducado y por eso se ha creado un objeto PrintStream.

Aquí tienes el ejemplo re-escrito para utilizar las clases Reader y Writer (observa la utilización de PipedReader y PipedWriter en lugar de PipedInputStream y PipedOutputStream) y la utilización de un API no caducado:

RhymingWords.java

import java.io.*;

class RhymingWords {
    public static void main(String[] args) {

        try {
            FileReader words = new FileReader("words.txt");

                // do the reversing and sorting
            Reader rhymedWords = reverse(sort(reverse(words)));

                // write new list to standard out
            BufferedReader br = new BufferedReader(rhymedWords);
            String input;
	    PrintWriter stdout = new PrintWriter(System.out, true);

            while ((input = br.readLine()) != null) {
                stdout.println(input);
            }
            br.close();

        } catch (Exception e) {
            System.err.println("RhymingWords: " + e);
        }
    }

    public static Reader reverse(Reader source) {
        PipedWriter pw = null;
        PipedReader pr = null;

        try {
            BufferedReader br = new BufferedReader(source);

            pw = new PipedWriter();
            pr = new PipedReader(pw);
            PrintWriter output = new PrintWriter(pw);

            new WriteReversedThread(output, br).start();

        } catch (Exception e) {
            System.err.println("RhymingWords reverse: " + e);
        }
        return pr;
    }

    public static Reader sort(Reader source) {
        PipedWriter pw = null;
        PipedReader pr = null;

        try {
            BufferedReader br = new BufferedReader(source);

            pw = new PipedWriter();
            pr = new PipedReader(pw);
            PrintWriter output = new PrintWriter(pw);

            new SortThread(output, br).start();

        } catch (Exception e) {
            System.err.println("RhymingWords sort: " + e);
        }
        return pr;
    }
}
WriteReversedThread.java
import java.io.*;

class WriteReversedThread extends Thread {
    PrintWriter pw;
    BufferedReader br;

    WriteReversedThread(PrintWriter pw, BufferedReader br) {
        this.pw = pw;
        this.br = br;
    }

    public void run() {
        if (pw != null && br != null) {
            try {
                String input;
                while ((input = br.readLine()) != null) {
                    pw.println(reverseIt(input));
                    pw.flush();
                }
                pw.close();
            } catch (IOException e) {
                System.err.println("WriteReversedThread run: " + e);
            }
        }
    }

    protected void finalize() {
        try {
            if (pw != null) {
                pw.close();
                pw = null;
            }
            if (br != null) {
                br.close();
                br = null;
            }
        } catch (IOException e) {
            System.err.println("WriteReversedThread finalize: " + e);
        }
    }

    private String reverseIt(String source) {
        int i, len = source.length();
        StringBuffer dest = new StringBuffer(len);

        for (i = (len - 1); i >= 0; i--) {
            dest.append(source.charAt(i));
        }
        return dest.toString();
    }
}
SortThread.java
import java.io.*;

class SortThread extends Thread {
    PrintWriter pw;
    BufferedReader br;

    SortThread(PrintWriter pw, BufferedReader br) {
        this.pw = pw;
        this.br = br;
    }

    public void run() {
         int MAXWORDS = 50;

        if (pw != null && br != null) {
            try {
                String[] listOfWords = new String[MAXWORDS];
                int numwords = 0, i = 0;
 
                while ((listOfWords[numwords] = br.readLine()) != null) {
                    numwords++;
                }
                quicksort(listOfWords, 0, numwords-1);
                for (i = 0; i < numwords; i++) {
                    pw.println(listOfWords[i]);
                }
                pw.close();
            } catch (IOException e) {
                System.err.println("WriteReversedThread run: " + e);
            }
        }
    }

    protected void finalize() {
        try {
            if (pw != null) {
                pw.close();
                pw = null;
            }
            if (br != null) {
                br.close();
                br = null;
            }
        } catch (IOException e) {
            System.err.println("WriteReversedThread finalize: " + e);
        }
    }

    private static void quicksort(String[] a, int lo0, int hi0) {
        int lo = lo0;
        int hi = hi0;
        if (lo >= hi) {
            return;
        }
        String mid = a[(lo + hi) / 2];
        while (lo < hi) {
            while (lo<hi && a[lo].compareTo(mid) < 0) {
                lo++;
            }
            while (lo<hi && a[hi].compareTo(mid) > 0) {
                hi--;
            }
            if (lo < hi) {
                String T = a[lo];
                a[lo] = a[hi];
                a[hi] = T;
            }
        }
        if (hi < lo) {
            int T = hi;
            hi = lo;
            lo = T;
        }
        quicksort(a, lo0, lo);
        quicksort(a, lo == lo0 ? lo+1 : lo, hi0);
    }
}


Ozito