Используйте синглтоны в akka scala actor - PullRequest
5 голосов
/ 04 марта 2011

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

class MyActor extends Actor{
  def receive()={
    case ACase => singleton.amethod()  
    case BCase => singleton.bmethod()
     }
 }

val singleton = new MyActorLogic

class MyActorLogic{
 val map:Map[String, Object] = Map()
 def amethod()=//alter the map

 def readMap(value:String) = map(value)    }                

Могут ли быть какие-либо побочные эффекты /проблемы?Спасибо

Ответы [ 2 ]

9 голосов
/ 04 марта 2011

Делай не делай это по любой причине в мире. Поверь мне.

Если вам нужны такие вещи, используйте вместо них Agent, вот для чего они хороши:

http://doc.akka.io/docs/akka/2.0.4/scala/agents.html

3 голосов
/ 04 марта 2011

Теоретически, использование MyActorLogic, вооруженного простой изменяемой картой из нескольких потоков, может привести к исключению одновременной модификации (когда один поток пересекает карту, в то время как другой ее модифицирует).

Вы можете сделать следующее, чтобы избежать проблем:

  1. Поместите карту в актера (как приватный участник). В Akka вы не работаете с экземпляром Actor напрямую (а обращаетесь к нему через прокси - ActorRef). В этом случае безопасный доступ к карте будет гарантирован не только актером, который всегда обрабатывает одно сообщение за раз - другие потоки не смогут получить доступ к закрытым элементам даже через отражение.
  2. Вы можете сделать методы обновления / поиска MyActorLogic поточно-ориентированными (например, сделать их synchronized)
  3. Вы можете использовать старый-добрый ConcurrentHashMap
  4. Вместо val map:mutable.Map вы можете использовать var map:immutable.Map. Таким образом, несколько потоков, обращающихся к map, могут иногда работать с устаревшими данными, но одновременных модификаций не будет (подход копирования при записи).

Только для заметки, истинный синглтон будет:

object MyActorLogic{
 val map:Map[String, Object] = Map()
 ...
...