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

时间:2011-03-04 02:39:45

标签: multithreading scala actor akka

我有一个将调用委托给有状态单身人士的演员。单例是有状态的,因为它维护着一个对象图。这个单例对象只用在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)    }                

可能有任何副作用/问题吗? 感谢

2 个答案:

答案 0 :(得分:9)

世界上出于任何原因这样做。 相信我。

如果您需要使用代理,请使用代理,这就是它们的优点:

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

答案 1 :(得分:3)

理论上,使用来自多个线程的简单可变映射的MyActorLogic可能会导致并发修改异常(当一个线程遍历映射时,另一个线程正在修改它)。

您可以执行以下操作以避免出现问题:

  1. 将地图放入演员(作为私人会员)。在Akka中,您没有直接使用Actor实例(而是通过代理访问它 - ActorRef)。在这种情况下,演员不仅可以保证对地图的安全访问,它总是一次处理一条消息 - 其他线程即使通过反射也无法访问私有成员。
  2. 您可以使MyActorLogic线程安全的更新/检索方法(例如,使它们成为synchronized
  3. 您可以使用旧的ConcurrentHashMap
  4. 您可以使用val map:mutable.Map代替var map:immutable.Map。因此,访问map的多个线程有时可能会使用陈旧数据,但不会有并发修改(写时复制方法)。

  5. 只是为了说明,真正的单身人士将是:

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