Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8014239

PipedInputStream not notifying waiting readers on receive

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • 7
    • core-libs

      FULL PRODUCT VERSION :
      java version " 1.7.0_21 "
      Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
      Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      When reading/writing from PipedInputStream/PipedOutputStream pair, read() blocks exactly for one second when new data is written into PipedOutputStream. The reason for this is that PipedInputStream only wakes waiting readers, when during receive() the buffer is filled.
      The solution is very simple, add a notifyAll() at the end of both receive() methods in PipedInputStream.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See the attached minimal example.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The elapsed time should be a few tens of milliseconds.
      ACTUAL -
      The elapsed time ALWAYS is 1000 milliseconds.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class Demo implements Runnable {

          private final InputStream in;

          public Demo(InputStream in) {
              this.in = in;
          }

          public static void main(String[] args) throws IOException, InterruptedException {
              PipedInputStream inStream = new PipedInputStream();
              PipedOutputStream outStream = new PipedOutputStream(inStream);
              Demo d = new Demo(inStream);
              Thread runThread = new Thread(d);
              runThread.start();
              Thread.sleep(1000);
              byte[] message = new byte[5];
              new Random().nextBytes(message);
              long startTime = System.currentTimeMillis();
              outStream.write(message);
              runThread.join();
              System.out.println( " Elapsed time: " + (System.currentTimeMillis() - startTime));
          }

          @Override
          public void run() {
              try {
                  byte[] message = new byte[5];
                  int nRead = in.read(message);
                  System.out.println(Arrays.toString(message));
              } catch (IOException ioe) {
                  System.out.println(ioe + ioe.getMessage());
              }
          }
      }
      ---------- END SOURCE ----------

            prappo Pavel Rappo
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: