2011-01-21 3 views
0

Проблема, с которой я сталкиваюсь, у меня есть поток A и n работы. Thread A должен подождать, пока это n полностью не будет выполнено. Моя идея заключается в использовании CountDownLatch с подсчетом n и использованием шаблона Producer/Consumer для управления Рабочем.Подождите, пока ровно n выполненных работ: Производитель, потребитель и счетчик

Я использую AtomicInteger, чтобы служить в качестве счетчика: Производитель проверяет, превышает ли значение счетчика значение 0, затем поместите сигнал на BlockingQueue, если значение счетчика меньше или равно 0, Производитель положил стоп-сигнал на очередь. Потребитель берет из очереди, проверяет, не является ли сигнал равным stopSignal, затем используйте ExecutorService, чтобы запланировать Worker.

Рабочий вызова getAndDecrement и проверить, если значение счетчика больше 0, если да, то делать работу, , если работа будет сделана, то это вызывает CountDownLatch # обратный отсчет еще увеличивает счетчик с incrementAndGet

Проблемы в том когда работа не будет выполнена, Рабочий должен увеличить счетчик, но это после getAndDecrement, чтобы Производитель мог видеть значение счетчика равным 0 и поставить сигнал останова, даже общая работа меньше n!

+0

Не могли бы вы просто начать точно * n * threads и 'join()' их всех? Просто возможно. – 9000

+0

Я не могу, потому что n может быть большим, скажем тысяча. – robinmag

ответ

1

Похоже, вы работаете над типичной проблемой производителя/потребителя с некоторой дополнительной сложностью (новое условие ожидания ровно n работы). Итак, как вы определили, у вас есть Продюсеры и Потребители. Один делает работу, второй потребляет ее.

Приращение после создания работы. Сокращение после того, как работа будет потреблена. Такой подход заставил бы ваших работников пытаться извлечь из очереди только тогда, когда есть доступная работа.

Теперь, чтобы решить вашу проблему, новое условие, в котором вы ожидаете завершения работы n. Если вы ожидаете завершения определенного количества заданий, и вы четко знаете об этих работах, вы можете использовать объект CyclicBarrier, чтобы остановить поток, пока все задания не достигли барьера.

Обычно существует несколько способов взаимодействия двух координатных работников в параллельной ситуации. Производитель/Потребитель может не быть решением этой проблемы, и ни один из них не может быть Барьером. Я бы порекомендовал посмотреть в пакете java.util.concurrent, так как он может пролить свет на эту тему.

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