Создание нового потока — довольно дорогостоящая операция, поскольку включает взаимодействие с операционной системой. Если ваша программа создает большое количество кратковременных потоков, то имеет смысл использовать пул потоков. Пул потоков содержит множество простаивающих потоков, готовых к запуску. Вы помещаете Runnable в пул, и один из потоков вызывает его метод run(). Когда метод run() завершается, поток не уничтожается и остается в пуле в готовности обслужить новый запрос.
Другая причина для использования пула потоков — необходимость ограничить количество конкурирующих потоков. Создание огромного числа потоков может пагубно отразиться на производительность, и даже привести к краху виртуальной машины. Если у вас есть алгоритм, создающий большое количество потоков, то вам следует установить «фиксированный» пул потоков, который ограничит общее количество конкурирующих потоков.
Класс Executors имеет ряд статических методов-фабрик для конструирования пулов потоков.