Executors.newVirtualThreadPerTaskExecutor()
Создаёт сервис, который запускает каждую задачу в отдельном виртуальном потоке.
Доступно с: Java 21
Синтаксис
public static ExecutorService newVirtualThreadPerTaskExecutor()Возвращаемое значение
ExecutorServiceСервис, создающий новый виртуальный поток на каждую задачу.
Примеры
Тысяча «запросов» с ожиданием выполняется параллельно:
int fetchPrice(int id) throws InterruptedException {
Thread.sleep(200);
return id % 10;
}
void main() throws Exception {
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
List<Future<Integer>> futures = new ArrayList<>();
for (int id = 0; id < 1000; id++) {
int x = id;
futures.add(executor.submit(() -> fetchPrice(x)));
}
int total = 0;
for (var f : futures) total += f.get();
IO.println("total = " + total);
}
}Результат:
total = 4500Примечания
Тысяча задач по 200 мс завершается примерно за 200 мс, а не за 200 секунд: каждая ждёт в своём виртуальном потоке. Ограничивать число потоков не нужно; если нужно ограничить нагрузку на внешний сервис, используйте Semaphore. Закрывайте сервис через try-with-resources.
См. также
- Thread.ofVirtual() — Создаёт виртуальный поток — лёгкий поток, которых можно запустить миллионы.
- ExecutorService — Сервис, который выполняет задачи в пуле потоков.
- ExecutorService.close() — Закрывает пул и ждёт завершения всех задач; вызывается автоматически в try-with-resources.
Вопросы и ответы по теме
В учебнике
- Виртуальные потоки — Виртуальные потоки в Java 21+ — чем они отличаются от обычных, Thread.ofVirtual, newVirtualThreadPerTaskExecutor, тысячи задач сразу и ограничение через Semaphore.