Search code examples
javajava-threadsthread-synchronization

Java Thread state when performing I/O operations


Suppose a Java thread performs some I/O operation like reading a file with traditional blocking Java I/O.

The question is: What is the state of the thread while waiting?

I don't know if it is RUNNING (doing some active wait) or WAITING (maybe there is some kind of monitor that wakes up the thread when file data is ready).

How can I find it out?


Solution

  • A thread that is blocked in an I/O syscall should be in RUNNABLE state, according to my reading of the javadocs.

    public static final Thread.State RUNNABLE

    Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

    The other possible thread states are far more tightly specified, and the respective specifications make them clearly inapplicable.

    I have confirmed this by testing (with OpenJDK Java 8 on Linux).

    public class Test {
        public static void main(String[] args) throws Exception {
            Thread t = new Thread(new Runnable() {
                    public void run() {
                        try {
                            while (true) {
                                System.in.read();   // Block for input
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            t.start();
            while (true) {
                System.out.println("State: " + t.getState());
                Thread.sleep(1000);
            }
        }
    }
    

    Now, hypothetically, if you designed your application so that one thread handed off I/O requests to second thread, then the first thread would be in WAITING (or possibly BLOCKED) state waiting for the I/O thread to deliver. However, normal Java I/O doesn't behave like that. The thread requesting I/O is the one that makes the syscall.

    How can I find it out?

    • Write tests; see above.
    • Deep-dive the OpenJDK source code.