2011-03-04 21 views
5

Tengo un actor que está delegando llamadas a un singleton con estado. El singleton es estable porque mantiene un mapa de objetos. Este objeto singleton se usa solo en el actor y en una clase (no actor) donde estoy recuperando un objeto en este mapa (así que solo lectura segura de subprocesos).Usar singletons en akka scala actor

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) }     

¿Puede haber algún efecto secundario/problema? Gracias

Respuesta

9

Haz no hacer eso por cualquier razón en el mundo. Confía en mí.

Si necesita ese tipo de cosas utilizar el agente de cambio, que es lo que son buenas para:

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

+0

He resuelto poner un mapa en el actor y consultar al actor. Entonces, el singleton se ha incorporado al actor y no expone nada. Estoy empezando a pensar que los actores y la inyección de dependencia no son buenos amigos. ¿Estoy en lo cierto? – Matroska

+2

DI funciona bien, incluso tenemos una integración de Spring y una integración de Guice. –

+1

Una breve explicación haría de esto una respuesta mucho más útil. ¿Cuál es el razonamiento detrás de no seguir el enfoque en la pregunta? ¿Por qué es inferior a, por ejemplo, encapsular el mapa en el actor o usar Agentes? – mahonya

3

En teoría, usar MyActorLogic, armado con un mapa mutable simple, de múltiples hilos, puede llevar a una excepción de modificación concurrente (cuando un hilo atraviesa el mapa, mientras que otro lo modifica).

que podría hacer lo siguiente para evitar problemas:

  1. Poner en el mapa el actor (como un miembro privado). En Akka, no está trabajando directamente con la instancia Actor (sino más bien accediéndola a través de un proxy - ActorRef). En este caso, el acceso seguro al mapa no solo estará garantizado por el actor, que siempre procesa un mensaje a la vez: otros hilos no podrán acceder a los miembros privados, incluso a través de la reflexión.
  2. Usted puede hacer que los métodos de actualización/recuperación de MyActorLogic flujos seguros (por ejemplo, haciéndolos synchronized)
  3. Puede usar la vieja buena ConcurrentHashMap
  4. En lugar de val map:mutable.Map puede utilizar var map:immutable.Map. Por lo tanto, los subprocesos múltiples que acceden a map pueden ocasionalmente trabajar con datos obsoletos, pero no habrá modificaciones concurrentes (enfoque de copiado en escritura).

Sólo por la nota, la verdadera Singleton sería:

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

que seguirá la primera sugerencia. Estoy usando el nuevo operador porque los objetos no son divisibles para pruebas unitarias. Pero también estoy usando patrones de tortas, así que probablemente pueda burlarme de objetos con patrones de tortas. Gracias – Matroska

+0

Nunca endosaré algo así. Solo mendiga por problemas. –

Cuestiones relacionadas