← Назад к вопросам
Что такое ThreadPool?
2.0 Middle🔥 241 комментариев
#JVM и управление памятью#Многопоточность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
ThreadPool: управление потоками в Java
ThreadPool (пул потоков) — это коллекция переиспользуемых потоков, которые ждут назначения задач. Вместо создания нового потока для каждой задачи, мы используем уже созданные потоки из пула, что значительно улучшает производительность.
Проблема без ThreadPool
// ❌ Плохо — создаём новый поток на каждую задачу
public void processRequests(List<Task> tasks) {
for (Task task : tasks) {
new Thread(() -> {
task.execute();
}).start();
}
}
// Проблемы:
// - Создание потока дорого (требует памяти и времени)
// - Неограниченное количество потоков → OutOfMemoryError
// - Плохая производительность (context switching)
// - Сложно управлять потоками
ThreadPool решение
// ✅ Хорошо — используем пул потоков
ExecutorService executor = Executors.newFixedThreadPool(10);
public void processRequests(List<Task> tasks) {
for (Task task : tasks) {
executor.submit(() -> {
task.execute();
});
}
}
// Преимущества:
// - Потоки переиспользуются
// - Ограниченное количество потоков
// - Очередь задач (queue)
// - Управление жизненным циклом
Как работает ThreadPool
┌─────────────────────────────────────────┐
│ ThreadPool (10 потоков) │
├─────────────────────────────────────────┤
│ [Thread-1] [Thread-2] ... [Thread-10] │
│ (работают) │
└──────────┬──────────────────────────────┘
│
┌────▼────────────────┐
│ Queue (FIFO) │
│ [Task-1] │
│ [Task-2] │
│ [Task-3] │
│ ... (до 100 задач) │
└─────────────────────┘
Если поток свободен → берёт следующую задачу из очереди
Если все потоки заняты → задача ждёт в очереди
Если очередь переполнена → выполняется policy (reject/wait/etc)
Типы ExecutorService
1. FixedThreadPool — фиксированное количество потоков
// Самый частый выбор
ExecutorService executor = Executors.newFixedThreadPool(10);
// Создаёт 10 потоков, которые живут вечно
// Новые задачи добавляются в очередь
// Идеально для:
// - Обработки HTTP запросов
// - Параллельных вычислений
// - Фоновых задач с ограничением нагрузки
for (int i = 0; i < 100; i++) {
final int id = i;
executor.submit(() -> {
System.out.println("Task " + id + " on thread " + Thread.currentThread().getName());
// Поток возвращается в пул
});
}
2. CachedThreadPool — создаёт потоки по необходимости
// Гибкий пул
ExecutorService executor = Executors.newCachedThreadPool();
// Создаёт новые потоки по необходимости
// Переиспользует неиспользуемые потоки (timeout 60 сек)
// Идеально для:
// - Коротких асинхронных задач
// - Когда нагрузка непредсказуема
// - Когда задачи могут блокировать друг друга
// ⚠️ Опасность: может создать слишком много потоков
3. SingleThreadExecutor — один поток
// Для последовательной обработки задач
ExecutorService executor = Executors.newSingleThreadExecutor();
// Все задачи выполняются в одном потоке
// Гарантирует FIFO порядок
// Идеально для:
// - Обработки событий
// - Где важен порядок выполнения
// - Избежание race conditions
executor.submit(() -> System.out.println("Task 1")); // Выполнится первой
executor.submit(() -> System.out.println("Task 2")); // Выполнится второй
4. ScheduledExecutorService — планирование задач
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
// Выполнить один раз через 2 секунды
executor.schedule(() -> {
System.out.println("Delayed task");
}, 2, TimeUnit.SECONDS);
// Выполнить периодически (начало через 1 сек, повтор каждые 2 сек)
executor.scheduleAtFixedRate(() -> {
System.out.println("Periodic task");
}, 1, 2, TimeUnit.SECONDS);
// Выполнить периодически (задержка между завершением и следующим стартом)
executor.scheduleWithFixedDelay(() -> {
System.out.println("Task with delay");
}, 1, 2, TimeUnit.SECONDS);
Конфигурация ThreadPool
// Использование ThreadPoolExecutor для полного контроля
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // corePoolSize — минимум потоков
10, // maximumPoolSize — максимум потоков
60, // keepAliveTime
TimeUnit.SECONDS, // время жизни неиспользуемого потока
new LinkedBlockingQueue<>(100), // очередь для задач
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy() // policy при переполнении очереди
);
// Policy при переполнении очереди:
// - AbortPolicy: выброс исключения (по умолчанию)
// - CallerRunsPolicy: вызывающий поток выполняет задачу
// - DiscardPolicy: отброс задачи
// - DiscardOldestPolicy: отброс самой старой задачи в очереди
Практический пример
public class ApiService {
private final ExecutorService executor = Executors.newFixedThreadPool(20);
// Обработка HTTP запроса в отдельном потоке
public void handleRequest(HttpRequest request, HttpResponse response) {
executor.submit(() -> {
try {
// Обработка может быть долгой (DB запрос, внешний API)
String result = processRequest(request);
response.write(result);
} catch (Exception e) {
response.writeError(e);
}
});
}
// Корректное завершение
public void shutdown() {
executor.shutdown();
try {
if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}
}
}
Жизненный цикл
ExecutorService executor = Executors.newFixedThreadPool(5);
// 1. Добавление задач (активно)
executor.submit(task1);
executor.submit(task2);
// 2. Остановка новых задач
executor.shutdown(); // Мягкое завершение
// или
executor.shutdownNow(); // Принудительное завершение (может привести к потере)
// 3. Ожидание завершения
boolean finished = executor.awaitTermination(5, TimeUnit.MINUTES);
if (!finished) {
System.err.println("Pool did not terminate");
}
Когда использовать ThreadPool
✅ Сервер обработки HTTP запросов ✅ Параллельные вычисления ✅ Фоновые асинхронные задачи ✅ Периодические scheduled задачи ✅ Обработка событий из queue ✅ Spring Boot (автоматически использует ThreadPool)
❌ Вычисления в одном потоке ❌ Стартап приложения ❌ Быстрые синхронные операции
Мониторинг ThreadPool
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
// Статистика
System.out.println("Active threads: " + executor.getActiveCount());
System.out.println("Core pool size: " + executor.getCorePoolSize());
System.out.println("Max pool size: " + executor.getMaximumPoolSize());
System.out.println("Queue size: " + executor.getQueue().size());
System.out.println("Completed tasks: " + executor.getCompletedTaskCount());
ThreadPool — это фундаментальная концепция для масштабируемых и производительных Java приложений.