在阿卡·斯卡拉演员中使用单身人士
问题描述:
我有一个演员正在将呼叫委派给有状态的单身人士。单身人士是有状态的,因为它保持着物体的地图。这个单例对象只用在actor和一个类(不是actor)中,我在这个map中检索一个对象(所以只是线程安全读取)。在阿卡·斯卡拉演员中使用单身人士
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) }
会有任何副作用/问题吗? 感谢
答
答
从理论上讲,使用MyActorLogic
,用一个简单的可变地图武装,从多个线程,可能会导致并发修改异常(当一个线程正在地图上,而另一个人修改它)。
你可以做到以下几点,以避免出现问题:
- 把地图分成演员(如私有成员)。在
Akka
中,您不直接使用Actor
实例(而是通过代理访问它 -ActorRef
)。在这种情况下,对地图的安全访问将不仅由参与者保证,而且一次处理一条消息 - 其他线程即使通过反射也无法访问私人成员。 - 您可以
MyActorLogic
线程安全的(例如,使他们) - 您可以使用旧的好
ConcurrentHashMap
- 相反
val map:mutable.Map
,你可以用var map:immutable.Map
的更新/检索方法。因此,访问map
的多个线程偶尔可能会使用陈旧的数据,但不会有并发修改(写时复制方法)。
只是为了说明,真正的单身是:
object MyActorLogic{
val map:Map[String, Object] = Map()
...
+0
我将按照第一个建议。我正在使用新的操作符,因为对象不能用于单元测试。但我也使用了蛋糕模式,所以我可能会用蛋糕模式来模拟对象。谢谢 – Matroska 2011-03-04 13:01:40
+0
我绝对不会赞同这样的。这只是乞求问题。 – 2011-03-04 15:11:18
我已经解决了将地图放入演员和查询演员。所以这个单身人士已经被纳入演员,并且不会暴露任何东西。我开始认为演员和依赖注入不是好朋友。我对吗? – Matroska 2011-03-04 16:12:04
DI工作得很好,我们甚至有一个Spring集成和一个Guice集成。 – 2011-03-05 00:06:13
简单的解释会使这个更有用的答案。在问题中不遵循方法的原因是什么?为什么它不如说,封装在演员地图或使用代理? – mahonya 2015-09-18 16:56:11