I/O-methods like read() 如何在 java 中将线程置于阻塞状态?

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

所以,如果我没有理解错的话,当我们在一个对象上调用 wait 时线程进入等待状态,当它等待对象上的锁时进入阻塞状态(比如试图进入同步块或方法)。

I/O-methods 如何像 read() 那样将线程置于阻塞状态?我明白为什么它必须处于阻塞状态,等待它可以读取的数据,但我也对如何进行感兴趣。当试图读取的资源中的数据再次可用时,JVM 如何通知线程它可以继续?

这取决于原生平台。

在 POSIX 中,对 read 的调用通常会阻塞,直到数据可用为止,但是 return 有许多其他原因,例如已到达文件末尾,文件描述符已关闭,操作超时或信号中断操作。

在Windows中,关系最密切的函数是ReadFile


血淋淋的细节,参考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,调用 IO_Read.

在POSIX中,IO_Read is defined as handleRead, which calls read. The RESTARTABLE宏在出错时循环,errnoEINTR

在Windows、IO_Read is defined as handleRead中调用ReadFile.

它不会将线程状态更改为 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();
}

打印

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

相反,OS 不会从 read return 直到有一些数据并且 OS 决定是否以及何时切换 [=22] =].

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

OS在有更多数据或流已关闭时唤醒线程。 JVM 不参与。