// File: IO11.java // // Author: Rahul Simha // Created: Nov 28, 1998 // // Concurrent Producer-Consumer that // illustrates OutputStreamWriter and PrintWriter. import java.awt.*; import java.awt.event.*; import java.io.*; class Producer extends Frame implements Runnable { Label L; // A place to write stuff. OutputStream out_stream; public Producer (OutputStream out_stream) { // Store the reference to the output stream. this.out_stream = out_stream; // Create the frame. this.setSize (600,100); this.setLocation (0,100); this.setTitle ("Producer"); this.setBackground (Color.white); // this.setLayout (new BorderLayout()); // This is where we will write to. L = new Label (""); this.add (L, BorderLayout.CENTER); this.setVisible (true); } // Must implement the run() method. public void run () { try { byte separator = 127; DataOutputStream dos = new DataOutputStream (out_stream); dos.writeInt (5); out_stream.write (separator); dos.writeChars ("ABC"); out_stream.write (separator); PrintWriter pw = new PrintWriter (out_stream, true); pw.print (5); pw.flush (); out_stream.write (separator); pw.print ("ABC"); pw.flush (); out_stream.write (separator); L.setText ("5, ABC, 5, ABC"); } catch (IOException e) { System.out.println (e); } // Write EOF and close output stream. try { out_stream.write (-1); out_stream.close (); } catch (IOException e) { System.out.println (e); } L.setText (L.getText() + " Done!"); } } class Consumer extends Frame implements Runnable { Label L; // Data similar to Producer. InputStream in_stream; public Consumer (InputStream in_stream) { this.in_stream = in_stream; this.setSize (600,100); this.setLocation (0, 200); this.setTitle ("Consumer"); this.setBackground (Color.white); // this.setLayout (new BorderLayout()); L = new Label (""); this.add (L, BorderLayout.CENTER); this.setVisible (true); } public void run () { // Read byte values until EOF. while (true) { // Get the next byte int i = -1; try { i = in_stream.read (); } catch (IOException e) { System.out.println (e); } // Extract byte. byte k = (byte) i; // Check if end-of-data. if ( (i < 0) || (k < 0) ) break; String hex = Integer.toHexString (k); System.out.println ("Consumer: just read " + k + " (Hex: " + hex + ")"); // Write it on the frame. L.setText (L.getText() + " " + hex); // Sleep for a while. try { Thread.sleep ((int)UniformRandom.uniform(5,10)); } catch (InterruptedException e) { System.out.println (e); } } L.setText (L.getText() + " Done!"); try { in_stream.close (); } catch (IOException e) { System.out.println (e); } } } // This is an independent quit button to quit the application. class QuitButton extends Frame { public QuitButton () { this.setSize (80,50); this.setLocation (0, 0); this.setTitle ("Quit button"); Button quitb = new Button ("QUIT"); quitb.setBackground (Color.red); quitb.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { System.exit (0); } } ); this.add (quitb, BorderLayout.CENTER); this.setVisible (true); } } public class IO11 { public static void main (String[] argv) { // Create an independent quit button. QuitButton q = new QuitButton (); try { // Create the matching pipes. Note that one pipe // is given to the constructor of the other. PipedOutputStream pipe_out = new PipedOutputStream (); PipedInputStream pipe_in = new PipedInputStream (pipe_out); // Create a producer instance and thread. Producer p = new Producer (pipe_out); Thread pthread = new Thread (p); // Create a consumer instance and thread. Consumer c = new Consumer (pipe_in); Thread cthread = new Thread (c); // Start the threads. pthread.start(); cthread.start(); } catch (IOException e) { System.out.println (e); } } }