Что такое Virtual Threads и как они меняют разработку?
Virtual Threads (Project Loom, Java 21) — легковесные потоки, управляемые JVM, которые позволяют использовать простой синхронный код с масштабируемостью реактивного стека.
Аналогия из жизни: обычные (platform) потоки — это дорогие сотрудники, которых можно нанять ограниченное количество. Virtual Threads — это волонтёры: их может быть миллион, и они “спят”, пока ждут ответа, не потребляя ресурсов.
Включение в Spring Boot
Пример
spring:
threads:
virtual:
enabled: true
Одна строка — и все HTTP-обработчики, Kafka listeners, scheduled tasks переключаются на виртуальные потоки.
До и после Virtual Threads
Пример
// До: реактивный стек для масштабируемости
public Mono<Order> getOrder(UUID id) {
return orderRepository.findById(id)
.switchIfEmpty(Mono.error(new OrderNotFoundException(id)))
.flatMap(order -> enrichWithCustomer(order));
}
// После: простой синхронный код с той же масштабируемостью
public Order getOrder(UUID id) {
Order order = orderRepository.findById(id)
.orElseThrow(() -> new OrderNotFoundException(id));
return enrichWithCustomer(order);
}
Structured Concurrency (Java 24+)
Пример
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Subtask<User> userTask = scope.fork(() -> findUser(userId));
Subtask<Order> orderTask = scope.fork(() -> findOrder(orderId));
scope.join().throwIfFailed();
return new UserOrder(userTask.get(), orderTask.get());
}
Частые ошибки
- Блокирующие операции (synchronized) на виртуальных потоках: pinning виртуального потока к carrier thread. Используйте ReentrantLock вместо synchronized
- Попытка пулить виртуальные потоки — они создаются по одному на задачу, пул не нужен
- Предположение, что Virtual Threads ускоряют CPU-bound задачи — они помогают только для I/O-bound
Как используется в 2026
Virtual Threads стали стандартом для Spring Boot приложений. Реактивный стек (WebFlux, R2DBC) остаётся релевантным для изначально реактивных систем, но для типичного enterprise-приложения Virtual Threads устраняют основную мотивацию использования реактивного подхода.
На собеседовании: главное — объяснить разницу между platform threads и virtual threads: platform thread = обёртка над OS thread (ограничен тысячами), virtual thread = управляется JVM (миллионы). Упомяните pinning как главную проблему и ReentrantLock как решение. Бонус: “Virtual Threads не заменяют реактивный стек полностью — для backpressure и streaming WebFlux остаётся актуальным”.