Ответ
Поток переходит в состояние BLOCKED и освобождает процессорное время (CPU). Он будет находиться в этом состоянии до тех пор, пока операция ввода-вывода не завершится на уровне операционной системы (например, данные не будут прочитаны с диска или из сети).
Ключевые моменты:
- Блокировка: Поток «засыпает», ожидая данных. Это неэффективно с точки зрения использования ресурсов, особенно при большом количестве одновременных соединений.
- Освобождение CPU: Планировщик потоков JVM может выполнять другие готовые к работе (RUNNABLE) потоки.
Пример блокирующего чтения из файла:
try (FileInputStream fis = new FileInputStream("data.txt")) {
int byteData;
// Поток блокируется на каждом вызове read(), пока байт не будет доступен
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData);
}
} catch (IOException e) {
e.printStackTrace();
}
Альтернативы для избежания блокировки:
- Неблокирующий I/O (NIO) с Selector: Поток может опрашивать множество каналов на готовность, не блокируясь на каждом.
- Асинхронный I/O (NIO.2): Операция инициируется и завершается в фоновом режиме, уведомляя поток через callback или Future.
- Использование пула потоков: Блокирующие операции делегируются отдельным потокам из пула, чтобы основной поток (например, в веб-сервере) мог продолжать принимать новые запросы.