7

I have a very basic question. If a thread is busy in IO operation why it is not considered in a RUNNING state? If the IO operation is taking long time it means that the thread is doing its work. How can a thread be called BLOCKED when it is actually doing it's work?

user1877246
  • 449
  • 1
  • 6
  • 9
  • check this http://stackoverflow.com/questions/13596997/why-is-the-cpu-not-needed-to-service-i-o-requests – Changgeng Nov 14 '13 at 15:34
  • It is not doing any work, it is not running on a core, it is using no CPU, so considering it 'RUNNING' is not exactly appropriate! – Martin James Nov 14 '13 at 15:48
  • Perhaps you confuse the term "blocked" in the thread context, with the "blocking I/O operation" which means something a bit different. – BartoszKP Nov 14 '13 at 15:49
  • User threads do not, (usually), do I/O operations directly. They request the OS to do them and block until they are done. Drivers do the actual I/O and signal the user threads to run again when the operation is completed. – Martin James Nov 14 '13 at 15:53

2 Answers2

5

I don't know where you read that a thread is in the BLOCKED state when doing IO. The BLOCKED state documentation says:

Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

So, no, a thread is not in a blocked state while doing IO (unless of course reading or writing forces it to wait on an object's monitor).

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
5

If you run the following code with a thread blocking on IO

public class Main {
    public static void main(String[] args) throws  InterruptedException {
        final Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // blocking read
                try {
                    System.in.read();
                } catch (IOException e) {
                    throw new AssertionError(e);
                }
            }
        });
        thread.start();
        for(int i=0;i<3;i++) {
            System.out.println("Thread status: "+thread.getState());
            Thread.sleep(200);
        }
        System.exit(0);
    }
}

prints

Thread status: RUNNABLE
Thread status: RUNNABLE
Thread status: RUNNABLE
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • So, a thread state being `RUNNABLE` on blocking IO is nothing but occupying CPU time slice, doing nothing but waiting on IO response. Isn't it? – overexchange Dec 01 '17 at 09:34
  • @overexchange when a thread is blocking, it doesn't use the CPU (except to enter and exit this mode) The confusion is due to the fact the JVM doesn't know when a blocking system call is made as the OS decides this. – Peter Lawrey Dec 01 '17 at 10:48
  • Despite allocated time slice, thread on blocking IO, doesn't require CPU for that time slice, which is understood, but no other thread is using that CPU, for that time slice. Isn't it? – overexchange Dec 01 '17 at 10:53
  • @overexchange if a thread is on a blocking IO, the OS can either pass the CPU to another thread so it can do useful work, or it can make the CPU idle to save power. – Peter Lawrey Dec 01 '17 at 11:33
  • @overexchange if you don't call any blocking operations, yes. Note, with non-blocking IO it is common to use a Selector which blocks. – Peter Lawrey Dec 01 '17 at 14:46
  • So, with nio, thread stays in infinite loop to sniff the selectors available to talk to. So, this thread requires CPU. Isn’t it? – overexchange Dec 02 '17 at 01:49
  • @overexchange yes. Though busy waiting on selectNow creates an insane amount if garbage unfortunately so don't do that. Instead i busy poll on a small number of connections. – Peter Lawrey Dec 02 '17 at 03:29