Search code examples
javamultithreadingsocketsconcurrencybufferedreader

block BufferedReader until data appears


Im not sure If I have this description correct, but here goes with the explanation.

I have a client side message processing system, that looks much like this: (it runs in a separate thread)

public void run() {
    String line;

    while(true)
    {
        try
        {
            while ((line = reader.readLine( )) == null) { Thread.sleep(10); }; 

            if (line.toUpperCase().startsWith("PING ")) {
                // Autorespond to server pings
                server.Write("PONG " + line.substring(5));
            }
            else {
                setChanged();
                notifyObservers(line);
            }
        }
        catch (Exception e)
        {
            //do something here
        }
    }

}

What I really, REALLY, want to do, is replace this line: while ((line = reader.readLine( )) == null) { Thread.sleep(10); } with something else, anything else, that isn't an essentially infinite loop.

Code Breakdown Loop forever until line contains some data. If its a ping request, auto respond and start over. If its not, notify the observer with the message received, and then start over.

The observer model works, not worried about that. The reader actually does work, as is...but it consumes a LOT of processor sitting there in an infinite loop, checking things.

The Question How can I use some kind of concurrency, wait, or whatever model so that the thread itself will simply wait until the BufferedReader actually has data to read? Is there even a way to do that, or is that Thread.Sleep(10) I added actually the best way to keep from eating all my processor ad infinitum.


Solution

  • What I really, REALLY, want to do, is replace this line: while ((line = reader.readLine( )) == null) { Thread.sleep(10); } with something else, anything else, that isn't an essentially infinite loop.

    You have a basic misunderstanding here. readLine() does block until data appears. It only returns null when you have reached end of stream, i.e. end of file or the peer has closed the connection. You don't need the sleep; you just need to reverse the test to != null and put the code that handles the data inside the loop.

    At the moment you are spinning in your loop at end of stream, which will never terminate.