Вы можете использовать BlockingQueue для определения задач.Пусть один поток создаст задачи и добавит их в очередь, используя put
, которая блокирует, пока в очереди не останется места.Затем пусть каждый рабочий поток просто вытаскивает следующую задачу из очереди.Характер блокировки очереди в основном заставит этот первый поток (определяющий задачи) не слишком сильно опережать рабочих.
Это действительно просто случай модель производитель-потребитель где вещь, которая производится и потребляется, является запросом на выполнение какой-либо работы.
Вам нужно будет указать какой-то способ завершения всего процесса после завершения всей работы.Один из способов сделать это - поместить N «ядовитых таблеток» в очередь, когда генерирующий поток создал все задачи.Это специальные задачи, которые просто сообщают рабочему потоку о выходе (вместо выполнения некоторой работы и последующего запроса следующего элемента).Поскольку каждый поток может прочитать только одну таблетку с ядом (поскольку он выходит после того, как прочитает ее), и вы положили в очередь N таблеток с ядом, вы убедитесь, что каждый из ваших потоков N увидит ровно одну таблетку с ядом.
Обратите внимание, что если поток, генерирующий задачи, потребляет ресурсы, например, соединение с базой данных для чтения задач, эти ресурсы будут удерживаться до тех пор, пока не будут созданы все задачи - что может занять некоторое время!Как правило, это не очень хорошая идея, поэтому в таких случаях такой подход не очень хорош.