Что такое 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 задачи.