ExecutorService: как запускать потоки и не уронить прод



В прошлый раз мы выбрали правильные коллекции. Но сама по себе потокобезопасная структура мертва, пока её не начнут дергать потоки.

Типичная ошибка — породить тысячу тредов через `new Thread()`:

// ПЛОХОЙ КОД
for (int i = 0; i < 1000; i++) {
new Thread(() -> callApi(i)).start();
}

ОС просто убьет такой процесс из-за нехватки ресурсов или задушит переключениями контекста.

Как делаем мы
Используем пул потоков (ExecutorService). Мы описываем задачу, а пул сам решает, какой свободный воркер её заберет.

Базовый шаблон работы выглядит так:

/

/ Пул размером с количество ядер CPU
ExecutorService executor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()
);

// Запускаем задачи
for (int i = 0; i < 10_000; i++) {
int id = i;
// submit возвращает Future — ручку для отслеживания результата
executor.submit(() -> processTask(id));
}

// Мягко останавливаем прием новых задач
executor.shutdown();

try {
// Ждем завершения запущенных (максимум 2 минуты)
if (!executor.awaitTermination(2, TimeUnit.MINUTES)) {
System.err.println("Принудительная отмена");
executor.shutdownNow();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Восстанавливаем флаг прерывания
executor.shutdownNow();
}

Три правила, чтобы спать спокойно:

* Исключения. Ошибки внутри обычного Runnable проглатываются. Если хотим их видеть — используем Callable<V> и вызываем future.get(). Там любое исключение вылетит наружу в виде ExecutionException.
* Размер пула. Для тяжелых вычислений (CPU-bound) ставим столько нитей, сколько физических ядер. Для ожидания сети или диска (IO-bound) — больше, например (ядра * 2), чтобы пока одни спят, другие работали.
* Shutdown vs ShutdownNow. Первый мягко закрывает входную дверь. Второй пытается прервать уже работающие нити через thread.interrupt(). Наш код обязан уметь обрабатывать InterruptedException и быстро завершаться.

Забудьте про ручной new Thread(). Любой фоновый чих должен идти через ExecutorService. Это дает контроль над памятью и позволяет приложению нормально закрыться.
Просмотры: 69
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти