Миграция с параллелизма Java на параллелизм Scala - PullRequest
6 голосов
/ 05 июня 2009

У меня достаточно стандартный механизм в Java для решения проблемы:

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

Я использую следующее решение:

  1. Наличие однопоточного планировщика для планирования моих рабочих элементов
  2. Иметь ExecutorService (который может быть многопоточным)
  3. Каждый запланированный рабочий элемент затем передает фактическую работу на ExecutorService. Возвращенные Future кэшируются на карте. Служба завершения используется для удаления будущего из кэша, когда работа завершена
  4. Элементы могут быть отменены с помощью кэшированных фьючерсов

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

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

  1. Какой механизм я бы использовал для планирования рабочего элемента на определенное время?
  2. Если рабочий элемент - это событие, отправленное актеру, как я могу убедиться, что пул вспомогательных потоков больше, чем количество элементов, которые могут быть заблокированы одновременно
  3. Как мне отменить ранее запланированный рабочий элемент?

Ответы [ 2 ]

5 голосов
/ 06 июня 2009

Какой механизм я бы использовал для планирования рабочего элемента на определенное время?

Я бы использовал java.util.concurrent.ScheduledExecutorService.

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

Это кажется мне дизайном, который побеждает усилие распараллеливания. Попробуйте минимизировать или устранить блокировку и глобальное состояние. Это барьеры для компоновки и масштабируемости. Например, рассмотрим наличие отдельного выделенного потока, который ожидает поступления файлов и затем запускает события для участников. Или посмотрите на java.nio для асинхронного неблокирующего ввода-вывода.

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

Как можно отменить ранее запланированный рабочий элемент?

ScheduledExecutorService возвращает фьючерсы. То, что у вас есть, не плохой дизайн в этом отношении. Соберите их на карте и вызовите future.cancel ().

1 голос
/ 07 июня 2009

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

В блоге обсуждается этот вопрос Простой cron-подобный планировщик в Scala .

...