code: public synchronized int read()  throws IOException {
          if (!connected) {
              throw new IOException("Pipe not connected");
          } else if (closedByReader) {
              throw new IOException("Pipe closed");
          } else if (writeSide != null && !writeSide.isAlive()
                     && !closedByWriter && (in < 0)) {
              throw new IOException("Write end dead");
          }
  
          readSide = Thread.currentThread();
          int trials = 2;
          while (in < 0) {
              if (closedByWriter) {
                  /* closed by writer, return EOF */
                  return -1;
              }
              if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
                  throw new IOException("Pipe broken");
              }
              /* might be a writer waiting */
              notifyAll();
              try {
                  wait(1000);
              } catch (InterruptedException ex) {
                  throw new java.io.InterruptedIOException();
              }
          }
          int ret = buffer[out++];
          if (out >= buffer.length) {
              out = 0;
          }
          if (in == out) {
              /* now empty */
              in = -1;
          }
          return ret;
      }
docs: Reads the next character of data from this piped stream.
  If no character is available because the end of the stream
  has been reached, the value <code>-1</code> is returned.
  This method blocks until input data is available, the end of
  the stream is detected, or an exception is thrown.
  
  @return     the next character of data, or <code>-1</code> if the end of the
  stream is reached.
  @exception  IOException  if the pipe is
  <a href=PipedInputStream.html#BROKEN> <code>broken</code></a>,
  {@link #connect(java.io.PipedWriter) unconnected}, closed,
  or an I/O error occurs.