Шаблоны/Принципы для ориентированных на многопотоковое исполнение очередей и программы “ведущего устройства/рабочего” в Java

У меня есть проблема, которой я верю, классический шаблон ведущего устройства/рабочего, и я обращаюсь за советом на реализации. Вот то, что я в настоящее время думаю о проблеме:

Существует глобальная какая-то "очередь", и это - центральное место, где "работа, которая будет сделана", сохранена. По-видимому, этой очередью будет управлять своего рода "основной" объект. Потоки будут порождены для движения, ищут работу, чтобы сделать, и когда они найдут работу, чтобы сделать, они скажут основную вещь (безотносительно, который является) к тому, "добавьте это к очереди работы, которая будет сделана".

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

Я сделал изрядное количество программирования потока в Java в прошлом, но это все было до JDK 1.5, и следовательно я не знаком с соответствующими новыми API для обработки этого случая. Я понимаю, что JDK7 будет иметь соединение ветвления, и что это могло бы быть решением для меня, но я не могу использовать продукт раннего доступа в этом проекте.

Проблемы, поскольку я вижу их:

1) как иметь "потоки, делающие работу", связываются назад с ведущим устройством, говорящим им, что их работа завершена и что ведущее устройство может теперь удалить работу из очереди

2) как эффективно иметь основную гарантию, что работа только когда-либо планируется однажды. Например, скажем, у этой очереди есть миллион объектов, и она хочет сказать, что рабочий для "движения делает эти 100 вещей". Каков самый эффективный способ гарантировать, что, когда он планирует работу следующему рабочему, это получает "следующие 100 вещей" и не "эти 100 вещей, которые я уже запланировал"?

3) выбор соответствующей структуры данных для очереди. Мои взгляды здесь состоят в том, что "поиск работы потоков, чтобы сделать" мог потенциально найти тому же работу, чтобы сделать несколько раз, и они отправят, сообщение ведущему устройству, говорящему "вот работа", и ведущее устройство поняло бы, что работа была уже запланирована и следовательно должна проигнорировать сообщение. Я хочу удостовериться, чтобы я выбрал правильную структуру данных, таким образом, что это вычисление является максимально дешевым.

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

Довольно вероятно, что этой проблемой, которую я описываю, является типичная проблема с известным именем и принятым набором решений, но я, с моим непритязательным градусом неCS, не знаю то, чем это называют (т.е. быть нежным).

Спасибо за любого и все указатели.

11
задан marc esher 22 July 2009 в 11:38
поделиться

6 ответов

Насколько я понимаю ваши требования, вам понадобится ExecutorService . ExecutorService имеет метод

submit(Callable task)

, возвращаемое значение которого - Future . Будущее - это блокирующий способ обратной связи от рабочего к мастеру. Вы можете легко расширить этот механизм для работы в асинхронном режиме. И да, ExecutorService также поддерживает рабочую очередь, такую ​​как ThreadPoolExecutor. Так что в большинстве случаев вам не нужно беспокоиться о планировании. В пакете java.util.concurrent уже есть эффективные реализации потокобезопасной очереди (очередь ConcurrentLinked - неблокирующая и LinkedBlockedQueue - блокирующая).

7
ответ дан 3 December 2019 в 07:39
поделиться

Взгляните на java.util.concurrent в библиотеке Java.

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

Также может оказаться полезной книга Java Concurrency in Practice Брайана Гетца.

4
ответ дан 3 December 2019 в 07:39
поделиться

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

На ваши вопросы:

1) как заставить «потоки» выполнять работа "связаться с мастером говоря им, что их работа завершено, и теперь мастер может удалить работу из очереди

Мастер может слушать рабочих, используя шаблон слушатель / наблюдатель

2) как эффективно иметь мастера гарантия, что работа только когда-либо запланировано один раз. Например, скажем в этой очереди миллион элементов, и она хочет сказать работнику «иди, сделай это 100 вещей ". Что самое эффективное способ гарантировать, что когда это расписывает работу следующему работнику, это получает "следующие 100 вещей", а не "100 вещей, которые я уже запланировано »?

См. выше. Я бы позволил рабочим вытаскивать элементы из очереди.

3) выбор подходящих данных структура для очереди. Мое мышление вот что "темы, находящие работу делать "потенциально может найти то же самое работать надо делать больше одного раза, и они отправить сообщение мастеру, говоря "вот работа", и мастер понять, что работа уже была запланированы и, следовательно, должны игнорируйте сообщение. Я хочу убедиться что я выбираю правильную структуру данных так что это вычисление так же дешево насколько возможно.

Существуют реализации блокирующей очереди , начиная с Java 5

4
ответ дан 3 December 2019 в 07:39
поделиться

Не забывайте Jini и Javaspaces. То, что вы описываете, очень похоже на классический паттерн производитель / потребитель, которым выделяются космические архитектуры.

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

Вы можете тривиально масштабировать это, добавив больше потребителей. Это особенно хорошо работает, когда потребителями являются отдельные виртуальные машины, и вы масштабируете сеть.

1
ответ дан 3 December 2019 в 07:39
поделиться

Если вы открыты для идеи Spring, ознакомьтесь с их проектом Spring Integration. Он дает вам весь шаблон очереди / пула потоков из коробки и позволяет вам сосредоточиться на бизнес-логике. Конфигурация сведена к минимуму с помощью @annotations.

кстати, Goetz очень хорош.

0
ответ дан 3 December 2019 в 07:39
поделиться

This doesn't sound like a master-worker problem, but a specialized client above a threadpool. Given that you have a lot of scavenging threads and not a lot of processing units, it may be worthwhile simply doing a scavaging pass and then a computing pass. By storing the work items in a Set, the uniqueness constraint will remove duplicates. The second pass can submit all of the work to an ExecutorService to perform the process in parallel.

A master-worker model generally assumes that the data provider has all of the work and supplies it to the master to manage. The master controls the work execution and deals with distributed computation, time-outs, failures, retries, etc. A fork-join abstraction is a recursive rather than iterative data provider. A map-reduce abstraction is a multi-step master-worker that is useful in certain scenarios.

A good example of master-worker is for trivially parallel problems, such as finding prime numbers. Another is a data load where each entry is independant (validate, transform, stage). The need to process a known working set, handle failures, etc. is what makes a master-worker model different than a thread-pool. This is why a master must be in control and pushes the work units out, whereas a threadpool allows workers to pull work from a shared queue.

0
ответ дан 3 December 2019 в 07:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: