【发布时间】:2017-12-17 00:47:18
【问题描述】:
在 Akka 文档 (https://doc.akka.io/docs/akka/current/actors.html) 中,我发现了以下使用 Props 的推荐做法,但不明白为什么以另一种方式这样做会“不安全”(请参阅下面的代码 sn-p 和注释 // Props(new DemoActor(42)) 不安全。
问题:为什么“不保留对其封闭范围的引用”是首选,违反这一点可能会导致问题?
以下来自 Akka 文档。
推荐实践:最好在每个 Actor 的伴随对象上提供工厂方法,这有助于使合适的 Prop 的创建尽可能接近 Actor 定义。这也避免了使用 Props.apply(...) 方法相关的陷阱,该方法接受一个名称参数,因为在伴随对象中,给定的代码块将不保留对其封闭范围的引用:
object DemoActor {
/**
* Create Props for an actor of this type.
*
* @param magicNumber The magic number to be passed to this actor’s constructor.
* @return a Props for creating this actor, which can then be further configured
* (e.g. calling `.withDispatcher()` on it)
*/
def props(magicNumber: Int): Props = Props(new DemoActor(magicNumber))
}
class DemoActor(magicNumber: Int) extends Actor {
def receive = {
case x: Int ⇒ sender() ! (x + magicNumber)
}
}
class SomeOtherActor extends Actor {
// Props(new DemoActor(42)) would not be safe
context.actorOf(DemoActor.props(42), "demo")
// ...
}
Akka 文档提供的解释是
不建议在另一个actor中使用此方法,因为它鼓励关闭封闭范围,导致不可序列化的道具和可能的竞争条件(破坏actor封装)。
// NOT RECOMMENDED within another actor:
// encourages to close over enclosing class
val props7 = Props(new MyActor)
但我仍然无法完全理解它为什么会导致不可序列化的 Props 和可能的竞争条件......
【问题讨论】:
标签: akka