title: Block I/O in InputStream's read()
body: <p>I'm trying to write an algorithm, that downloads a video live stream. Specifically, the respective stream I'm trying to fetch is based on a dynamic <strong>.m3u8</strong> playlist file, which periodically provides URIs of new video files. The main goal is to combine those individual media files into one coherent InputStream.<br>
  I actually succeeded in getting it to work: I periodically check for new media files, that appear inside the playlist, and pass their HTTP streams to a custom InputStream implementation, namely <a href="http://paranoid-engineering.blogspot.de/2008/11/inputstreamchain.html" rel="nofollow">InputStreamChain</a>. Since it's a live stream, I assume it to be <em>endless</em>, at least for the time being. Ergo, I wanted my <code>InputStreamChain</code>'s <code>read()</code> never to send the -1. Unfortunately, it did; every time when all queued media streams were consumed, the <code>InputStreamChain</code> ended. Instead, I wanted it to block I/O, until a new media file arrives.
  So, I came up with a working solution: I adjusted the <code>read()</code> method to loop until there's a new stream available (a <code>TimerTask</code> will provide the new files). In the loop, I built in a <code>Thread.sleep()</code>, in order to reduce the CPU load:</p>
  
  <pre><code>public int read() throws IOException {  
      int bit = current.read();  
      if (bit == -1 &amp;&amp; streams.size() &gt; 0) {  
          // left out due to lacking relevance
      } else if(bit == -1 &amp;&amp; streams.size() == 0) {
          while(streams.size() == 0) {
              Thread.currentThread().sleep(50);
          }
          return read();
      }
      return bit;
  }
  </code></pre>
  
  <p>Although it seems to work, I have a feeling, that I'm not doing it how I'm supposed to. I also tried using <code>Lock</code> together with <code>Condition.await()</code>, but when my <code>TimerTask</code> tried to trigger <code>Condition.signal()</code>, it just threw a <code>IllegalMonitorStateException</code>.<br>
  That's why I'm asking the <strong>question</strong>:  </p>
  
  <p>In what way should I delay/block an InputStream's <code>read()</code> method, especially in my scenario?</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>For the sake of completeness, I'm going to provide my failed <code>Lock</code> approach, too:</p>
  
  <pre><code>private ReentrantLock ioLock;
  private Condition ioCond;
  private boolean waitingForStream = false;
  
  public InputStreamChain() {
      ioLock = new ReentrantLock();
      ioCond = ioLock.newCondition();
  }
  
  public synchronized InputStreamChain addInputStream(final InputStream stream) {
      streams.addLast(stream);
      if (current == null) {
          current = streams.removeFirst();
      }
      if(waitingForStream) {
          ioCond.signal();
      }
      return this;
  }
  
  public int read() throws IOException {
      int bit = current.read();
      if (bit == -1 &amp;&amp; streams.size() &gt; 0) {
          // do stuff
      } else if(bit == -1) {
          waitingForStream = true;
          ioLock.lock();
          try {
              ioCond.await();
          } catch (InterruptedException e) {
              e.printStackTrace();
          } finally {
              waitingForStream = false;
              ioLock.unlock();
          }
          return read();
      }
      return bit;
  }
  </code></pre>