The underlying data source for some implementations of InputStream can signal that the end of the stream has been reached, and no more data will be sent. Until this signal is received, read operations on such a stream can block.

For example, an InputStream from a Socket socket will block, rather than returning EOF, until a TCP packet with the FIN flag set is received. When EOF is received from such a stream, you can be assured that all data sent on that socket has been reliably received, and you won't be able to read any more data. (If a blocking read results in an exception, on the other hand, some data may have been lost.)

Other streams, like those from a raw file or serial port, may lack a similar format or protocol to indicate that no more data will be available. Such streams can immediately return EOF (-1) rather than blocking when no data are currently available. In the absence of such a format or protocol, however, you can't be sure when the other side is done sending data.


With regard to your second question, it sounds like you may have had a race condition. Without seeing the code in question, I'm guessing that the problem actually lay in your method of "display". Perhaps the attempt to display by the second notification was somehow clobbering the work done during the first notification.


It returns -1 if it's end of stream. If stream is still open (i.e. socket connection) but no data has reached the reading side (server is slow, networks is slow,...) the read() blocks.

You don't need call available(). I have a hard time understanding your notification design, but you don't need any calls except read() itself. Method available() is there for convenience only.


OK, this is a bit of a mess so first thing lets clear this up: InputStream.read() blocking has nothing to do with multi-threading. If you have multiple threads reading from the same input stream and you trigger two events very close to each other - where each thread is trying to consume an event then you'd get corruption: the first thread to read will get some bytes (possibly all the bytes) and when the second thread gets scheduled it will read the rest of the bytes. If you plan to use a single IO stream in more then one thread, always synchronized() {} on some external constraint.

Second, if you can read from your InputStream until you get -1 and then wait and can read again later, then the InputStream implementation you are using is broken! The contract for InputStream clearly states that an InputStream.read() should only return -1 when there is no more data to read because the end of the entire stream has been reached and no more data will EVER be available - like when you read from a file and you reach the end.

The behavior for "no more data is available now, please wait and you'll get more" is for read() to block and not return until there is some data available (or an exception is thrown).


By default the behavior of the provided RXTX InputStream is not compliant.

You have to set the receive threshold to 1 and disable the receive timeout:

serialPort.enableReceiveThreshold(1);
serialPort.disableReceiveTimeout();

Source: RXTX serial connection - issue with blocking read()