Миграция из параллелизма Java в параллелизм Scala
у меня довольно стандартный механизм в Java для решения проблемы:
- рабочие элементы должны быть запланированы для выполнения в определенное время
- каждый рабочий элемент должен затем ждать, когда условие станет истинным
- рабочие элементы должны быть отменены
решение я использую выглядит следующим образом:
- есть однопоточный планировщик для планирования моих рабочих элементов
- есть
ExecutorService
(который может быть многопоточный) - каждый запланированный рабочий элемент затем отправляет фактическую работу в
ExecutorService
. ВернувшийсяFuture
кэшируется на карте. Служба завершения используется для удаления будущего из кэша после завершения работы - элементы могут быть отменены через кэшированные фьючерсы
конечно, мой исполнитель должен быть по крайней мере таким же большим, как количество блокирующих рабочих элементов, которые я ожидаю, но это не проблема на практике.
Так что теперь я кодирование в Scala и использование структуры actor. Предполагая, что мой рабочий элемент может быть инкапсулирован в событие, отправленное актеру:
- какой механизм я бы использовал для планирования рабочего элемента на определенное время?
- если рабочий элемент-это событие, отправленное актору, как я могу гарантировать, что пул резервных потоков больше, чем количество элементов, которые могут блокироваться одновременно
- как я могу вызвать ранее запланированный рабочий элемент отменили?
2 ответов
какой механизм я бы использовал для планирования рабочего элемента на определенное время?
Я бы использовал java.утиль.параллельный.Scheduledexecutorservice выполняет.
Если рабочий элемент-это событие, отправленное актору, как я могу гарантировать, что пул резервных потоков больше, чем количество элементов, которые могут блокировать одновременно
Это меня поражает как дизайном, который побеждает усилий parallelisation. Попробуйте минимизировать или устранить блокирование и глобальное состояние. Это барьеры для композиционности и масштабируемости. Например, рассмотрим наличие одного выделенного потока, который ожидает поступления файлов, а затем запускает события для актеров. Или посмотрите на java.nio для асинхронного неблокирующего ввода-вывода
Я не полностью понимаю ваши требования здесь, но кажется, что у вас может быть один поток/актер, ищущий события ввода-вывода. Затем в качестве запланированных "рабочих элементов" запланируйте эффекты, которые создают неблокирующие актеры. Иметь эти субъекты регистрируются в потоке ввода-вывода/субъекте для получения сообщений о событиях ввода-вывода, которые им небезразличны.
Как я могу отменить ранее запланированный рабочий элемент?
ScheduledExecutorService
фьючерсы возвращает. Что у вас есть не плохой дизайн в этом отношении. Соберите их на карте и позвоните в future.аннулировать.)(
У вас может быть актер планирования, который имеет список запланированных актеров и использует актер.receiveWithin () просыпаться каждую секунду или около того и отправлять сообщения актерам, которые готовы к выполнению. Актер планирования также может обрабатывать отмену. Другой вариант-позволить каждому актору обрабатывать собственное планирование непосредственно с помощью receiveWithin () вместо централизации планирования.
есть некоторые обсуждения по этому вопросу в блогепростой cron, как планировщик в Scala.