многопоточность Java - дождитесь доступности свободных потоков для создания и назначения следующей задачи - PullRequest
0 голосов
/ 06 февраля 2019

В поисках подхода для решения проблемы многопоточности.У меня N задач, скажем, 100. Мне нужно выполнить эти 100 задач, используя ограниченное количество потоков, скажем, 4. Размер задачи огромен, поэтому я не хочу создавать все задачи вместе.Каждая задача будет создаваться только тогда, когда в пуле доступна свободная нить. Любое рекомендуемое решение для нее.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Вы можете использовать BlockingQueue для определения задач.Пусть один поток создаст задачи и добавит их в очередь, используя put, которая блокирует, пока в очереди не останется места.Затем пусть каждый рабочий поток просто вытаскивает следующую задачу из очереди.Характер блокировки очереди в основном заставит этот первый поток (определяющий задачи) не слишком сильно опережать рабочих.

Это действительно просто случай модель производитель-потребитель где вещь, которая производится и потребляется, является запросом на выполнение какой-либо работы.

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

Обратите внимание, что если поток, генерирующий задачи, потребляет ресурсы, например, соединение с базой данных для чтения задач, эти ресурсы будут удерживаться до тех пор, пока не будут созданы все задачи - что может занять некоторое время!Как правило, это не очень хорошая идея, поэтому в таких случаях такой подход не очень хорош.

0 голосов
/ 06 февраля 2019

Если вы можете получить количество активных потоков в определенный момент времени из пула потоков, вы можете решить свою проблему.Для этого вы можете использовать ThreadPoolExecutor#getActiveCount.Как только у вас будет номер активного потока, вы можете решить, создавать задачу или нет.

ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
executor.getActiveCount();

Примечание: ExecutorService не предоставляет метод getActiveCount, вы должны использовать ThreadPoolExecutor.ThreadPoolExecutor#getActiveCount Возвращает approximate число потоков, которые активно выполняют задачи.

...