Создание потока дорогостоящая операция.
Поэтому можно вместо создания новых потоков переиспользовать те которые завершили свою работу.
ExecutorService
помогает поддерживать пул потоков, то есть поддерживает выполнение некоторого фиксированного количества потоков, которые одновременно выполняются.
Также он назначает задачи этим потокам в этом пуле (в пуле всё время находятся те же самые потоки, это важно).
Он также предоставляет возможность ставить задачи в очередь до тех пор, пока не появится свободный поток в пуле, если количество задач превышает количество доступных потоков.
Как уже было сказано ExecutorService
создает некоторый пул потоков.
Например:
Если пул потоков имеет размер 10 то параллельно выполняться будет всего 10 потоков и как только один из 10 потоков завершит свою работу, он не создается заново, он перезапускается для выполнения уже другой задачи.
То есть потоки в пуле потоков не создаются заново, а переиспользуются.
Это частно может быть полезно в клиент-серверных программах.
То есть представим, что чтобы обработать один запрос клиента сервер создает отдельный поток. Когда серверной программой обрабатываются запросы клиентов, из-за большого количества потоков может увеличиваться время отклика (промежуток времени, который требуется серверу, чтобы обработать запрос извне). То есть требуется дополнительное время для постоянного создания нитей на сервере, что приводит к увеличению времени отклика и чтобы постоянно не создавались потоки на сервере дла обработки запросов, ExecutorService
может помочь. То есть запросы будут выполняться в ExecutorService, в котором потоки переиспользуются для обработки запросов клиентов, и если в ExecutorService нет места, запросы становиться в очередь и будут ждать пока освободиться поток в ExecutorService.
Также это полезно тем, что в процессе может создаться лишь ограниченное количество потоков. Благодаря ExecutorService больше заданного в конструкторе количества потоков не создастся и ясное дело ExecutorService экономит ресурсы и время. Достигается желаемая нагрузка и не подвергаются опасности системные ресурсы.
Пример программы:
Вывод:

То есть ExecutorService нам нужен чтобы некоторое количество потоков, некоторое продолжительное время переиспользовалось для выполнения каких-либо задач.