2013-11-12 5 views
1

Я работаю над проектом, в котором есть большой вход элементов данных, которые необходимо обработать. Обработка каждого не зависит от других, и мне нужно получить результат от каждого. Теперь я создаю задачу Callable для каждого элемента, который выполняет обработку, и используя ExecutorCompletionService для получения результата Future по мере завершения потоков.Определить количество выполненных задач в очереди ExecutorCompletionService

У меня тогда есть другой поток, который вытаскивает объекты Future из очереди ExecutorCompletionService. Этот поток просто вращается в бесконечном цикле while и вызывает take(), который блокируется до появления Future в очереди.

То, что я пытаюсь сделать, это избежать сценария, в котором очередь объектов Future растет быстрее, чем я вытаскиваю их из очереди, поэтому я хотел бы спать процесс, который создает задачи, если я отстану от обработки Future Результаты.

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу найти способ увидеть, сколько объектов Future находится в очереди ExecutorCompletionService. Есть ли способ сделать это?

Возможно, у меня есть внешний счетчик, который я увеличиваю при создании новой задачи и уменьшаюсь при обработке Future, но это только приводит меня к числу выдающихся задач, а не к числу действительно выполненных. Любые мысли о наилучшем способе борьбы с этим?

+0

Если вы также сохранить счетчик, который увеличивается (монотонно), когда новая задача представляется, то 'totalSubmitted - выдающийся = done', нет? – yshavit

+2

Можете ли вы перевернуть объекты через очередь пула и повторно использовать их? Это то, что я обычно делаю для межпоточного управления потоком объектов. Если пул заканчивается, поток, который создает задачи, блокируется в очереди пула, пока некоторые объекты не будут переработаны. –

+0

Спасибо вам обоим. yshavit, когда я говорю «выдающийся» выше, который включает в себя оба элемента, которые были отправлены и еще не завершены, и те, которые были завершены, но все еще находятся в очереди. У меня нет возможности узнать, как группа выдающихся предметов делится между этими группами. Мартин, мне нравится эта идея, и это звучит многообещающе. Я сделаю это. Я ценю вход. – nolt2232

ответ

1

Вы можете передать очереди, которые использует исполнитель, используя один из перегруженных конструкторов. Поскольку queue реализует Collection, вы можете просто вызвать .size() в этой очереди. У вас будет очередь для завершения и еще одна очередь для исполнителя, которую использует ExecutorCompletionService, чтобы вы могли рассказать, сколько из них представлено и сколько из них выполнено.

Вам нужно будет просто держаться за эти очереди после их создания и передавать его во все, что зависит от их размера.

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html показывает перегруженный конструктор

+0

Возможно ли, чтобы вы расширили на "и еще одну очередь для исполнителя, которую использует Служба Исполнителя, чтобы вы могли рассказать, сколько из них представлено." Не удается найти «отправленную» очередь. –

+1

Я имел в виду блокирующую очередь, указанную в конструкторе ThreadPoolExecutor http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html. Затем вы можете обернуть этот ThreadPoolExecutor в ExecutorCompletionService и различать размер этих очередей. –

Смежные вопросы