Раньше для параллельной обработки часто создавали пул обычных потоков:
ExecutorService executor = Executors.newFixedThreadPool(10);
Но если задачи в основном ждут сеть, базу данных, файлы или внешние API, обычные потоки могут быстро стать дорогими.
В Java 21 появились virtual threads:
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
Теперь можно запускать отдельный лёгкий поток под каждую задачу:
executor.submit(() -> sendEmail(user));
executor.submit(() -> generateReport(user));
executor.submit(() -> syncAnalytics(user));
Это особенно удобно для I/O-heavy сценариев: HTTP-запросов, JDBC, чтения файлов, отправки уведомлений и интеграций с внешними сервисами.
Важно: virtual threads не делают CPU-heavy код быстрее сами по себе.
Если задача активно считает, шифрует, парсит огромные данные или грузит процессор, лучше думать про обычный пул по числу ядер.
А вот для большого количества блокирующих операций virtual threads могут сильно упростить архитектуру.
👉 Java Ready | #совет
