Подтвердить что ты не робот

Поддержка Java для трех разных моделей concurrency

Я использую другую модель concurrency в многопоточной среде (http://tutorials.jenkov.com/java-concurrency/concurrency-models.html)

В статье рассказывается о трех моделях concurrency.

  • Параллельные рабочие

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

  • Линия сборки

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

    Каждый рабочий работает в своем потоке и не имеет отношения к другим рабочим. Это также иногда называют общей моделью concurrency.

  • Функциональный Parallelism

    Основная идея функционального parallelism заключается в том, что вы реализуете свою программу, используя вызовы функций. Функции можно рассматривать как " агенты" или " участники", которые отправляют сообщения друг другу, точно так же, как в модели конвейера concurrency (AKA реактивные или управляемые событиями системы). Когда одна функция вызывает другую, это похоже на отправку сообщения.

Теперь я хочу сопоставить поддержку API Java для этих трех концепций.

  • Параллельные рабочие: ExecutorService, ThreadPoolExecutor, CountDownLatch API?

  • Линия сборки. Отправка события в систему обмена сообщениями, например JMS, и использование концепций сообщений Очереди и темы.

  • Функциональный Parallelism: ForkJoinPool в некоторой степени и java 8 потоков. Бассейн ForkJoin легко понять по сравнению с потоками.

Правильно ли я сопоставляю эти модели concurrency? Если нет, пожалуйста, поправьте меня.

4b9b3361

Ответ 1

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

  • Параллельные рабочие: производитель создает новые задания где-то (например, в BlockingQueue), и многие потоки (через ExecutorService) обрабатывают эти задания параллельно. Конечно, вы также можете использовать CountDownLatch, но это означает, что вы хотите активировать действие после того, как были обработаны подпрограммы точно N (например, вы знаете, что ваша большая проблема может быть разбита на N более мелкие проблемы, проверьте второй пример здесь).
  • Линия сборки: для каждого промежуточного шага вы имеете BlockingQueue и один Thread или ExecutorService. На каждом шаге задания берутся из одного BlickingQueue и помещаются в следующий, для дальнейшей обработки. К вашей идее с JMS: JMS подключается к распределенным компонентам и является частью Java EE и не считается используемым в высоком параллельном контексте (сообщения обычно хранятся на жестком диске перед обработкой).
  • Функциональный Parallelism: ForkJoinPool является хорошим примером того, как вы могли реализовать это.

Ответ 2

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

Давайте начнем с ExecutorService. Он позволяет отправлять задачи, которые должны выполняться неблокируемым способом. Затем реализация ThreadPoolExecutor ограничивает максимальное количество доступных потоков. ExecutorService не требует выполнения задачи полного процесса, как вы могли бы ожидать от параллельного рабочего. Задача может быть ограничена определенной частью процесса и отправить сообщение по завершении, которое начнет следующий шаг на конвейере.

CountDownLatch и ExecutorService предоставляют средства для блокировки до тех пор, пока все рабочие не закончатся, что может пригодиться, если определенный процесс был разделен на разные параллельные подзадачи.

Точка JMS - это средство обмена сообщениями между компонентами. Он не применяет определенную модель для concurrency. Очереди и темы означают, как сообщение отправляется от издателя к подписчику. При использовании очередей сообщение отправляется ровно одному абоненту. С другой стороны, темы передают сообщение всем подписчикам темы.

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

ForkJoinPool - фактически одна реализация ExecutorService (которая может подчеркнуть сложность сопоставления модели и детали реализации). Это просто оптимизировано для работы с большим количеством небольших задач.

Резюме. Существует несколько способов реализации определенной модели concurrency в среде Java. Интерфейсы, классы и фреймворки, используемые при реализации программы, могут варьироваться независимо от выбранной модели concurrency.