在 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) }
会有任何副作用/问题吗? 谢谢
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 amethod()=//alter the map
def readMap(value:String) = map(value) }
Could there be any side effects/problems?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
无论出于何种原因,都不要这样做。
相信我。
如果您需要这类东西,请使用 Agent,这就是它们的优点:
http: //doc.akka.io/docs/akka/2.0.4/scala/agents.html
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
理论上,从多个线程使用带有简单可变映射的 MyActorLogic 可能会导致并发修改异常(当一个线程正在遍历映射,而另一个线程正在修改它时)。
您可以执行以下操作来避免出现问题:
Akka
中,您不直接使用Actor
实例(而是通过代理 -ActorRef
访问它)。在这种情况下,对映射的安全访问不仅由始终一次处理一条消息的参与者保证 - 其他线程即使通过反射也无法访问私有成员。MyActorLogic
的更新/检索方法成为线程安全的(例如,使它们同步
)。ConcurrentHashMap
var map:immutable.Map
。因此,访问map
的多个线程有时可能会处理过时的数据,但不会有并发修改(写时复制方法)。只是为了说明,真正的单例是:
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 :
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.MyActorLogic
thread-safe (e.g., making themsynchronized
)ConcurrentHashMap
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: