Какой новый механизм для управления пулами потоков (Thread Pool) появился в Java 21?

«Какой новый механизм для управления пулами потоков (Thread Pool) появился в Java 21?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Java 21 в качестве превью-фичи был представлен StructuredTaskScope (JEP 453) – не совсем thread pool, а API для структурированного параллелизма. Он предоставляет более безопасный и управляемый способ запуска и координации групп подзадач (часто выполняемых виртуальными потоками).

Ключевая идея: Задачи, запущенные в одном StructuredTaskScope, должны завершиться до того, как завершится работа самого scope (принцип «Обработка ошибок отменяет зависшие дочерние задачи»).

Пример использования:

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
    // "fork" запускает подзадачи (часто в виртуальных потоках)
    Future<String> userTask = scope.fork(() -> fetchUserFromDB());
    Future<Integer> orderTask = scope.fork(() -> fetchOrderFromAPI());

    scope.join();          // Ожидаем завершения ВСЕХ запущенных подзадач
    scope.throwIfFailed(); // Если любая подзадача завершилась с исключением – бросаем его

    // Получаем результаты только после успешного join
    String user = userTask.resultNow();
    Integer order = orderTask.resultNow();
    return new Response(user, order);
} // Scope автоматически закрывается, обеспечивая отмену незавершенных задач

Основные преимущества:

  • Автоматическое управление жизненным циклом: Задачи ограничены лексической областью видимости (try-with-resources).
  • Надежная обработка ошибок: Стратегии ShutdownOnFailure и ShutdownOnSuccess автоматически отменяют другие задачи при сбое или первом успешном результате.
  • Упрощение отмены (cancellation): Все дочерние задачи привязаны к сроку жизни родительского scope.
  • Идеальная интеграция с Virtual Threads: Эффективно управляет большим количеством легковесных задач.