Gymterview
middle

Что такое Virtual Threads (Project Loom)?

Virtual Threads — лёгкие потоки, управляемые JVM, а не операционной системой. Позволяют создавать миллионы потоков без значительных затрат памяти, решая проблему масштабирования блокирующего I/O.

Аналогия из жизни: platform threads — это такси (каждая машина стоит дорого, их количество ограничено), virtual threads — это велосипеды (дешёвые, можно выдать каждому). Когда велосипедист останавливается на светофоре (I/O), велосипед не занимает дорогу — другие могут проехать.

Platform Threads vs Virtual Threads

Критерий Platform Thread Virtual Thread
Стек ~1 MB (фиксированный) ~несколько KB (динамический)
Создание Дорого (syscall) Дёшево (объект JVM)
Количество Тысячи Миллионы
Планирование ОС JVM (ForkJoinPool)
Блокирующий I/O Блокирует поток ОС Отпускает carrier thread
CPU-bound Эффективен Не даёт преимущества
Пример: создание и использование Virtual Threads
// Создание Virtual Thread
Thread vThread = Thread.ofVirtual().start(() -> {
    System.out.println("Running in: " + Thread.currentThread());
});

// С именем
Thread.ofVirtual().name("my-vthread").start(() -> {
    // ...
});

// ExecutorService с Virtual Threads
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 100_000; i++) {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return fetchData();
        });
    }
} // executor.close() ждёт завершения всех задач

// Spring Boot — одна строка конфигурации
// application.yml:
// spring:
//   threads:
//     virtual:
//       enabled: true

Когда использовать

Сценарий Рекомендация
I/O-bound (HTTP, БД, файлы) Virtual Threads
Высокая конкурентность (тысячи соединений) Virtual Threads
Замена реактивного стека Virtual Threads (для 80% сценариев)
CPU-bound вычисления Platform Threads / ForkJoinPool
Код с synchronized + I/O (pinning) Заменить на ReentrantLock

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

  • Пул Virtual Threads — Executors.newFixedThreadPool() с Virtual Threads бессмысленно; используйте newVirtualThreadPerTaskExecutor()
  • ThreadLocal с Virtual Threads — при миллионе потоков ThreadLocal потребляет огромное количество памяти; используйте ScopedValues
  • synchronized с I/O — pinning; замените на ReentrantLock
  • Ожидать ускорение CPU-bound задач — Virtual Threads не добавляют ядра

Как используется в 2026

  • Spring Boot 3.2+ — spring.threads.virtual.enabled=true для MVC на Virtual Threads
  • Tomcat, Jetty, Undertow поддерживают Virtual Threads
  • JDBC-драйверы (PostgreSQL, MySQL) работают без pinning (заменили synchronized на ReentrantLock)
  • Virtual Threads + блокирующий код = альтернатива WebFlux для 80% сценариев

На собеседовании: объясните проблему platform threads (1 MB стек, лимит тысячи потоков), как virtual threads решают её (несколько KB, миллионы потоков), и обязательно упомяните pinning (synchronized + I/O блокирует carrier thread). Частая ошибка — сказать, что Virtual Threads ускоряют CPU-bound задачи.