Как методы ввода-вывода, такие как read(), переводят поток в заблокированное состояние в Java?

Итак, если я правильно понял, поток переходит в состояние ожидания, когда мы вызываем wait для объекта, и он переходит в заблокированное состояние, когда он ожидает блокировки объекта (например, при попытке попасть в синхронизированный блок или метод).).

Как методы ввода-вывода, такие как read(), переводят поток в заблокированное состояние? Я понимаю, ПОЧЕМУ он должен находиться в заблокированном состоянии, ожидая данных, которые он может прочитать, но меня также интересует КАК. Как JVM уведомляет поток о том, что он может продолжить работу, когда данные в ресурсе, который он пытается прочитать, снова становятся доступными?

2 ответа

Решение

Не изменяет состояние потока на 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

вместо этого ОС не возвращается из read пока не появятся какие-либо данные и ОС не решит, следует ли и когда контекст переключать поток / процесс.

Как JVM уведомляет поток о том, что он может продолжить работу, когда данные в ресурсе, который он пытается прочитать, снова становятся доступными?

ОС пробуждает поток, когда данных больше или поток закрыт. JVM не вмешивается.

Это зависит от родной платформы.

В POSIX, вызов read обычно блокируется до тех пор, пока данные не становятся доступными, но есть много других причин для возврата, например, достигнут конец файла, дескриптор файла был закрыт, тайм-аут операции или сигнал прервал операцию.

В Windows наиболее тесно связанная функция ReadFile,


Кровавые подробности, ссылающиеся на Java 8 update 112 b15:

FileInputStream.read называет родной FileInputStream.read0, реализованный непосредственно через JNI в Java_java_io_FileInputStream_read0, который вызывает readSingle, который вызывает IO_Read,

В POSIX, IO_Read определяется как handleRead, который вызывает read, RESTARTABLE макроциклы, пока есть ошибка и errno является EINTR,

В Windows IO_Read определяется как handleRead, который вызывает ReadFile,

Другие вопросы по тегам