user3954436
user3954436

Reputation:

Is BufferedReader.readLine() over a Socket a blocking operation?

I'm trying to get to run an example class that uses an Observer interface and an Observable subclass to check when the input stream from the socket is different from a null string. Here is the code (Observable class):

@Override
public void run() {
    String input;
    while (true) {
        try {
            input = reader.readLine();
            if (input != null) {
                setChanged();
                notifyObservers(input);
            } else
                System.out.println("Nothing read from the stream");
        } catch (IOException e) {
        }
    }
}

So, when the condition input != null is true, then the update() method is called and it outputs to the stdout what has been read from the socket. The server is sending a string every second and the observer checks it at max speed (without any sleep() calls). So, what really BufferedReader.readLine() does when reading from a stream that is owned by a socket? Because the else block is never executed.

Upvotes: 0

Views: 1909

Answers (2)

Holger
Holger

Reputation: 298539

You cannot create a BufferedReader around a socket as a BufferedReader simply wraps another Reader. Readers don’t support non-blocking I/O at all.

Before you can create a BufferedReader, you have to create a Reader:

Channels.newReader(…):

…if the channel is in non-blocking mode when bytes are to be read then an IllegalBlockingModeException will be thrown.

The similar thing will happen if you try the detour via an InputStream, e.g. acquired by Socket.getInputStream():

If the channel is in non-blocking mode then the input stream's read operations will throw an IllegalBlockingModeException.

So you can use BufferedReader.readLine() only when the socket is in blocking mode which implies that it will wait until at least one character could be read which is a different condition than end-of-stream. Hence, as Peter Lawrey pointed out, it will continue to read until either the line is complete or the stream reaches its end which implies in a blocking socket that the stream has been closed.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533870

As BufferedReader.readLine() states

A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

You will only get null when the other end closes the connection.

If you want to implement a busy waiting strategy, you could use non-blocking NIO, but be aware that this will use 100% of one CPU.

Upvotes: 1

Related Questions