Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does I/O-methods like read() put a Thread in blocked state in java?

So, if i have understood this correctly, a thread goes into waiting state when we call wait on an object and it goes into blocked state when it is waiting for a lock on an object(like when trying to get into a synchronized block or method).

How does I/O-methods like read() put a Thread in a blocked state though? I understand WHY it has to be in a blocked state, waiting for data that it can read but i'm also interested in HOW. How does the JVM notify the thread that it can continue when data in the resource its trying to read, is available again?

like image 847
Per Nissilä Avatar asked Dec 14 '16 11:12

Per Nissilä


2 Answers

It doesn't change the state of the thread to BLOCKED

public static void main(String[] args) throws IOException {
    Thread main = Thread.currentThread();
    new Thread(() -> {
        for (int i = 0; i < 10; i++) {
            System.out.println(main + " is in "+main.getState()+" state");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new AssertionError(e);
            }
        }
    }).start();
    System.in.read();
}

prints

Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state

instead the OS doesn't return from the read until there is some data and the OS decides whether and when to context switch the thread/process.

How does the JVM notify the thread that it can continue when data in the resource its trying to read, is available again?

The OS wakes the thread when there is more data or the stream has been closed. The JVM doesn't get involved.

like image 165
Peter Lawrey Avatar answered Oct 25 '22 09:10

Peter Lawrey


This depends on the native platform.

In POSIX, a call to read usually blocks until data is available, but there are many other reasons to return, such as an end-of-file was reached, the file descriptor was closed, the operation timed out or a signal interrupted the operation.

In Windows, the most closely related function is ReadFile.


The gory details, refering to Java 8 update 112 b15:

FileInputStream.read calls the native FileInputStream.read0, implemented natively through JNI in Java_java_io_FileInputStream_read0, which calls readSingle, which calls IO_Read.

In POSIX, IO_Read is defined as handleRead, which calls read. The RESTARTABLE macro loops while there's an error and the errno is EINTR.

In Windows, IO_Read is defined as handleRead, which calls ReadFile.

like image 42
acelent Avatar answered Oct 25 '22 10:10

acelent