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?
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With