Как методы ввода-вывода, такие как 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
,