简体   繁体   English

在akka scala演员中使用单身人士

[英]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). 这个单例对象只用在actor和一个类(不是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)    }                

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: 如果你需要那种东西而不是使用Agent,那就是它们有用的东西:

http://doc.akka.io/docs/akka/2.0.4/scala/agents.html 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). 理论上,使用MyActorLogic ,带有来自多个线程的简单可变映射,可能会导致并发修改异常(当一个线程遍历映射,而另一个线程正在修改它时)。

You could do the following to avoid problems : 您可以执行以下操作以避免出现问题:

  1. Put the map into the actor (as a private member). 将地图放入actor(作为私有成员)。 In Akka , you're not working with the Actor instance directly (but rather accessing it through a proxy - ActorRef ). Akka ,您不是直接使用Actor实例(而是通过代理 - 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. 在这种情况下,对actor的安全访问不仅会由actor保证,它总是一次处理一条消息 - 其他线程即使通过反射也无法访问私有成员。
  2. You can make update/retrieval methods of MyActorLogic thread-safe (eg, making them synchronized ) 您可以使MyActorLogic更新/检索方法是线程安全的(例如,使它们synchronized
  3. You can use old-good ConcurrentHashMap 您可以使用旧的ConcurrentHashMap
  4. Instead of val map:mutable.Map you can use var map:immutable.Map . 而不是val map:mutable.Map可以使用var map:immutable.Map Thus, multiple threads accessing map may occasionally work with a stale data, but there will be no concurrent modifications (copy-on-write approach). 因此,访问map多个线程可能偶尔使用陈旧数据,但不会有并发修改(写时复制方法)。

Just for the note, true singleton would be: 只是为了说明,真正的单身人士将是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM