Use singletons in akka scala actor
I have an actor that is delegating calls to a stateful singleton. The singleton is stateful since it is maintaining a map of objects. This singleton object is used just in the actor and in a class (not actor) where I am retrieving one object in this map (so just thread safe read).
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 amet开发者_开发技巧hod()=//alter the map
def readMap(value:String) = map(value) }
Could there be any side effects/problems? Thanks
Do not do that for any reason in the world. Trust me.
If you need that sort of things use Agent instead, that's what they are good for:
http://doc.akka.io/docs/akka/2.0.4/scala/agents.html
In theory, using MyActorLogic
, armed with a simple mutable map, from multiple threads, may lead to concurrent modification exception (when one thread is traversing the map, whilst another's modifying it).
You could do the following to avoid problems :
- Put the map into the actor (as a private member). In
Akka
, you're not working with theActor
instance directly (but rather accessing it through a proxy -ActorRef
). In this case, safe access to the map will not only be guaranteed by the actor, that always processes one message at a time - other threads won't be able to access private members even through reflection. - You can make update/retrieval methods of
MyActorLogic
thread-safe (e.g., making themsynchronized
) - You can use old-good
ConcurrentHashMap
- Instead of
val map:mutable.Map
you can usevar map:immutable.Map
. Thus, multiple threads accessingmap
may occasionally work with a stale data, but there will be no concurrent modifications (copy-on-write approach).
Just for the note, true singleton would be:
object MyActorLogic{
val map:Map[String, Object] = Map()
...
精彩评论