Пул рабочих потоков в Java
Очередь заказов приходит пачками: десять коротких отчётов за секунду. Десять новых потоков на каждую пачку быстро забьют память, а два постоянных работника с общей очередью справятся без лишних затрат на создание и уничтожение.
newFixedThreadPool(n) держит ровно потоков.
Лишние задачи ждут в очереди, пока кто-то из работников
освободится. Потоки не исчезают после одного прогона:
пул переиспользует их для следующих поручений.
Несколько задач подряд в пул из двух потоков:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(2);
for (int i = 1; i <= 4; i++) {
int id = i;
pool.execute(() -> {
System.out.println("task " + id + " on "
+ Thread.currentThread().getName());
});
}
pool.shutdown();
pool.awaitTermination(5, java.util.concurrent.TimeUnit.SECONDS);
}
}
В логе видно, что имена потоков повторяются: работа идёт
на ограниченном наборе исполнителей, а не на четырёх
разовых Thread.
У фабрики Executors есть и другие пресеты:
один фоновый поток, кэширующий пул с ростом по нагрузке,
планировщик с задержкой. Для сервиса с предсказуемой
нагрузкой чаще явно задают размер фиксированного пула
и не полагаются на бесконечный рост потоков.
Создайте пул из 3 потоков и отправьте в него
6 задач, каждая печатает своё число и имя
потока. Дождитесь завершения не дольше 10 секунд.