Ниже привожу небольшой конспект для собеседования по пулам:
1. Virtual Threads (JDK 21+)
Суть: Легковесные потоки, отвязанные от потоков ОС (carrier threads). Позволяют запускать миллионы потоков в одном JVM.
Применение: Только для I/O-bound задач (БД, HTTP, RPC). Код остается простым и синхронным.
Executor: Использовать
Executors.newVirtualThreadPerTaskExecutor(). Пулирование (newFixedThreadPool) не требуется и не рекомендуется.Важно: Не ускоряют CPU-bound вычисления.
2. Structured Concurrency (JDK 23-24 Preview, JDK 27 LTS)
Проблема: Обычный Executor порождает «сиротские» задачи (утечки, фоновые запросы после отмены родительского).
Решение: Управление группой потоков как единым блоком (
StructuredTaskScope).Гарантии: Автоматическая отмена всех дочерних задач при падении одной из них или отмене родителя. Нет утечек и «зомби-потоков».
3. Scoped Values (JDK 25 Stable)
Зачем: Замена
ThreadLocal.Плюсы: Неизменяемость, автоматическая очистка, отсутствие утечек памяти при миллионах виртуальных потоков. Передача контекста (например,
traceId) без риска оставить мусор в пуле.4. Подводные камни (Pitfalls)
Pinning: Виртуальный поток блокирует ОС-поток, если заходит в блок
synchronized (решено в JDK 24+) или вызывает нативный код (JNI). Старые драйверы БД могут стать узким местом.Инструменты: Дебаггеры и профилировщики в JDK 21–23 могут работать некорректно из-за continuations.
Просмотры: 11