Почему виртуальные потоки (Virtual Threads) в Java создают меньшую нагрузку на процессор?

«Почему виртуальные потоки (Virtual Threads) в Java создают меньшую нагрузку на процессор?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Виртуальные потоки (Project Loom) снижают нагрузку на CPU за счет устранения привязки потока платформы (OS thread) к потоку приложения. Они работают на уровне JVM, а не ОС.

Сравнение моделей:

Аспект Платформенный поток (Thread) Виртуальный поток (VirtualThread)
Ресурсы Дорогие (стек ~1 МБ), создаются ОС. Дешевые (стек в куче), создаются JVM.
Масштабирование Ограничено числом потоков ОС (~1000). Поддерживает миллионы потоков.
Блокировка Блокирует дорогой поток ОС, CPU простаивает. При блокировке (I/O) виртуальный поток "открепляется", а поток ОС выполняет другую задачу.

Ключевой механизм: Когда виртуальный поток выполняет блокирующую операцию (например, сетевой запрос), JVM приостанавливает его, а его поток-носитель (carrier thread) освобождается для выполнения другого виртуального потока. Это предотвращает простои дорогих ресурсов ОС.

Пример:

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10_000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1)); // Виртуальный поток приостанавливается здесь
            return i;
        });
    });
} // Запуск 10k "спящих" задач без создания 10k потоков ОС

Таким образом, виртуальные потоки позволяют эффективно использовать CPU для полезной работы, а не для переключения контекста между тысячами потоков ОС, ожидающих I/O.