многопоточность - Поддержка Java для трех разных моделей параллелизма



multithreading executorservice (2)

Я использую другую модель параллелизма в многопоточном окружении

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

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

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

  2. Сборочная линия

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

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

  3. Функциональный параллелизм

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

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

  1. Параллельные рабочие : это ExecutorService , ThreadPoolExecutor , CountDownLatch API?

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

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

Я прав в отображении этих моделей параллелизма? Если нет, пожалуйста, поправьте меня.


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

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

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

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

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

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

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

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

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





forkjoinpool