Как обрабатывать одновременный доступ к коллекции Scala? - PullRequest
10 голосов
/ 24 ноября 2011

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

В моей первой версии использовался ListBuffer, но я где-то читал, что он не предназначен для одновременного доступа. Я не получил исключения одновременного доступа, но я заметил, что поиск и удаление объектов из него не всегда работает, возможно, из-за параллелизма.

Я уже наполовину переписывал его, чтобы использовать Var List, но удаление элементов из неизменяемого List по умолчанию в Scala немного затруднительно - и я сомневаюсь, что он подходит для одновременного доступа.

Итак, основной вопрос: какой тип коллекции я должен использовать в ситуации одновременного доступа и как он используется?

(Возможно, второстепенно: Actor на самом деле является многопоточным объектом или это просто моя неправильная концепция, и он обрабатывает сообщения по одному в одном потоке?)

(Третичный: в Scala, какой тип коллекции лучше всего подходит для вставок и произвольного доступа (удаление / обновление)?)

Редактировать: Для добрых респондентов: Извините за поздний ответ, я делаю неприятную привычку: выкидывать вопрос в SO или списки рассылки, а затем переходить к следующей проблеме, забывая на данный момент исходную.

Ответы [ 4 ]

9 голосов
/ 24 ноября 2011

Посмотрите на scala.collection.mutable.Synchronized * traits / classes.

Идея состоит в том, чтобы объединить синхронизированные признаки в обычные изменяемые коллекции, чтобы получить их синхронизированные версии.

Например:

import scala.collection.mutable._
val syncSet = new HashSet[Int] with SynchronizedSet[Int]
val syncArray = new ArrayBuffer[Int] with SynchronizedBuffer[Int]
5 голосов
/ 24 ноября 2011

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

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

4 голосов
/ 24 ноября 2011

Неизменяемые коллекции Scala подходят для одновременного использования.

Что касается актеров, пара вещей гарантируется, как объяснено здесь документация Akka.

  • Правило отправки актера: где отправка сообщения актеру происходит до получения того же актера.
  • Правило последующей обработки актера: где обработка одного сообщения происходит до обработки следующего сообщения тем жеactor.

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

Таким образом, он заботится о постоянном состоянии данного Актера.Что касается общих данных, то, насколько я понимаю, лучший подход - это использовать неизменяемые структуры данных и максимально опираться на модель Actor.То есть «не общайтесь, разделяя память; делитесь памятью, общаясь».

0 голосов
/ 24 ноября 2011

Какой тип коллекции я должен использовать в ситуации одновременного доступа и как он используется?

См. Ответ @ hbatista.

Является ли актерна самом деле многопоточная сущность, или это просто моя неправильная концепция, и она обрабатывает сообщения по одному в одном потоке

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...