code: public int read(byte[] buf, int off, int len) throws IOException {
      while (true) {
        lockR.lock();
        try {
          int available = availableCount.get();
          if (available > 0) {
            // as long as there is available data
            // serve it even if closed
            final int lenToRead = Math.min(available, len);
            final int lenForward = Math.min(lenToRead, length - readCursor);
            final int lenRemaining = lenToRead - lenForward;
            
            // after readCursor
            if (lenForward > 0) {
              System.arraycopy(bytes, readCursor, buf, off, lenForward);
              incReadCursor(lenForward);
            }
            
            // before readCursor
            if (lenRemaining > 0) {
              System.arraycopy(bytes, 0, buf, off + lenForward, lenRemaining);
              incReadCursor(lenRemaining);
            } 
            availableCount.addAndGet(-1 * lenToRead);
            totalRead += lenToRead;
            return lenToRead;
          } else if (nonBlockingRead) {
            // we do not serve any bytes
            return 0;
          } else if (closed) {
            // when no bytes are left and buffer is closed
            // return -1
            return -1;
          }
        } finally {
          lockR.unlock();
        }
        sleep(1);
      }
    }
docs: Read data to the buffer, starting at offset off.
  Will block until data available, or the input has been closed.