Java BufferedReader readline blocking?

tgguy picture tgguy · May 5, 2010 · Viewed 10.9k times · Source

I want to make an HTTP request and then get the response as sketched here:

URLConnection c = new URL("http://foo.com").openConnection();
c.setDoOutput(true);

/* write an http request here using a new OutputStreamWriter(c.getOutputStream) */

BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream));
reader.readLine();

But my question is, if the request I send takes a long time before a response is received, what happens in the call reader.readLine() above? Will this process stay running/runnable on the CPU or will it get taken off the CPU and be notified to wake up and run again when there is IO to be read?

If it stays on the CPU, what can be done to make it get off and be notified later?

Answer

jasonmp85 picture jasonmp85 · May 20, 2010

What the others have said is correct. Java's "old I/O" library in java.io contains blocking calls. But they do not busy wait. They are blocking on I/O and the kernel will reschedule them once more I/O is available.

I wasn't totally sure, so I tried it out for myself. Take this sample class:

import java.io.*;

public class Test {

  public static void main(String[] args) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    String line = reader.readLine();
    System.out.println(line);
  }
}

And compile it on the command line. Then run it, but don't type anything. The program should be blocking on input until you type a character, and it will not progress past readline until you type enter. ps should be able to tell us more details about this process. Use the a flag to get more detailed information from ps:

japeters@<computer-name>] ps a
  PID   TT  STAT      TIME COMMAND
 3846 s000  S      0:00.16 -zsh
 3992 s000  S+     0:00.40 /usr/bin/java Test

The man page for PS says:

state The state is given by a sequence of characters, for example, ``RWNA''. The first character indicates the run state of the process:

  • I Marks a process that is idle (sleeping for longer than about 20 seconds).
  • R Marks a runnable process.
  • S Marks a process that is sleeping for less than about 20 seconds.

And since I just started the process, S makes sense. The process is sleeping, awaiting scheduling by the OS. Indeed, if you check top, you'll notice the process is taking 0% CPU.

So don't worry about the performance of this call, there's no busy waiting or polling going on: the system is taking care of the I/O events for you and will intelligently handle your process.