Получить доступ

Чем виртуальный поток отличается от обычного платформенного?

JuniorМногопоточностьJava >=21
Ещё спрашивают так:
  • Что такое Project Loom?
  • Когда использовать виртуальные потоки?
  • Ускоряют ли виртуальные потоки вычисления?
  • Чем virtual threads отличаются от platform threads?
Коротко

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

  • При блокировке на I/O отцепляется от несущего потока и освобождает его
  • Позволяет писать обычный блокирующий код и держать десятки тысяч соединений

А ещё Вычисления не ускоряют; пул для них не нужен — создают поток на задачу

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Платформенный поток — обёртка над потоком ОС: мегабайты памяти на стек и дорогие переключения ядром, поэтому их держат сотнями. Сервер «поток на запрос» упирается в это ограничение, и раньше приходилось переходить на асинхронный реактивный код.

Виртуальные потоки (Java 21, Project Loom) живут внутри JVM. Их выполняют несколько несущих платформенных потоков. Когда виртуальный поток блокируется на вводе-выводе (сеть, база, sleep), JVM снимает его с несущего потока и сохраняет стек в куче, а несущий поток берёт другую задачу. Когда данные пришли — поток продолжается.

Что это даёт: простой последовательный блокирующий код, который масштабируется до десятков и сотен тысяч одновременных операций ввода-вывода.

Что важно знать:

  • не ускоряют вычисления — для CPU-задач число ядер не меняется;
  • пул не нужен — создают поток на задачу (Executors.newVirtualThreadPerTaskExecutor()); ограничивать параллелизм к ресурсу лучше семафором;
  • pinning — в ранних версиях блокировка внутри synchronized «прикалывала» поток к несущему; в Java 24 это в основном исправлено;
  • много ThreadLocal становятся дорогими.

Пример

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    for (String url : urls) {
        executor.submit(() -> httpClient.send(request(url), ofString()));
    }
} // ждёт завершения всех задач

Что хотят услышать

  • Виртуальный поток управляется JVM и дешёв.
  • Механизм: отцепление от несущего потока при блокировке.
  • Для чего подходят (I/O) и для чего нет (вычисления).
  • Не нужно пулить — плюс.

Частые ошибки

  • Ожидать ускорения вычислительных задач.
  • Помещать виртуальные потоки в пул — они задуманы одноразовыми.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Он управляется средой выполнения Java, а не операционной системой, поэтому дёшев — их можно создавать миллионами
  • ✗Он выполняется быстрее за счёт компиляции в машинный код
  • ✗Он работает только с неблокирующим вводом-выводом
  • ✗Он не может выполнять код параллельно с другими потоками

Что спросят дальше

  • Что происходит с виртуальным потоком при блокирующем вызове?
  • Почему их не пулят?
  • Что такое pinning?
  • Как virtual threads влияют на Spring MVC?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем