在Akka文档(https://doc.akka.io/docs/akka/current/actors.html)中,我发现了以下推荐的使用道具的做法,但无法理解为什么这样做会“不安全”(请参阅下面的代码片段,注释 //道具(新的DemoActor(42))不安全 。
问题:为什么“不保留对其封闭范围的引用”是首选,否则可能导致问题?
以下是Akka文档。
推荐做法:最好在每个Actor的伴随对象上提供工厂方法,这有助于保持合适的Props的创建尽可能接近actor定义。这也避免了使用带有by-name参数的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中使用此方法,因为它鼓励关闭封闭范围,导致不可序列化的Props和可能的竞争条件(打破actor封装)。
// NOT RECOMMENDED within another actor:
// encourages to close over enclosing class
val props7 = Props(new MyActor)
但我仍然不完全理解为什么它会导致不可序列化的道具和可能的竞争条件...
答案 0 :(得分:0)
正如@chunjef所建议的那样,在这篇文章中提出并回答了问题:What does "to close over the enclosing scope/class" mean?