Akka文档记录了使用的危险变体Props:
// NOT RECOMMENDED within another actor:
// encourages to close over enclosing class
val props7 = Props(new MyActor)
Run Code Online (Sandbox Code Playgroud)
然后继续说明:
不推荐使用这种方法,因为它鼓励以关闭在所述封闭的范围,导致不可序列道具和可能的竞争条件(断裂演员封装)被另一个演员内使用.
有人可以解释一下"关闭封闭范围"的含义吗?一直在寻找,一无所获.谢谢.
agi*_*eel 19
在这个例子中看到,它new Actor被传递为一个所谓的"按名称"参数,这有点棘手.把它想象成它变成了类型的函数 () => Actor.每次重启时由其主管(重新)创建actor,都会调用此函数.
问题是这个函数是一个"闭包"(很容易谷歌;)),这意味着它捕获并记住它所需的周围范围内的所有东西(有时,但很少被称为"堆栈翻录").例如val f = (a: Int) => a + x.它x来自哪里?它来自周围的范围.分配给的函数litetal f称为"开放术语".在运行时,函数文字成为一个函数值(这是一种说"对象"的奇特方式),执行时会关闭开放项,同时捕获周围范围内的所有内容.这就是"封闭"这个名字的来源.
闭包是非常有用的,但你必须小心你关闭.有时x是一个def或上帝禁止a var,这导致不可预测的结果f,因为你无法控制f将被调用/执行的时间.试试看!
阿卡的两个非常常见的反模式是:
this从内部类创建Actor时关闭(外部)引用.def sender在回复带有未来的消息时关闭.我故意向谷歌提供了许多花哨的条款,顺便说一下;)
干杯和快乐的编码
作为@ agilesteel的正确答案的补充,一些参考:
解释什么是闭包:Scala编程,8.7,闭包
解释闭包可能导致序列化问题的原因:SIP-21 - 孢子
这是一个代码示例,根据SIP-21中的示例,创建一个不可序列化的Props对象,因为关闭了一个不可序列化的对象:
case class Helper(name: String)
object MyNonserializableObject {
val helper = Helper("the helper")
val props7 = Props(new MyActor(helper))
}
Run Code Online (Sandbox Code Playgroud)
即使它helper本身是可序列化的,"新的MyActor(帮助器)"也是按名称传递的,因此捕获this.helper,并且this不可序列化.
您可以看到actor参数是通过名称从Props apply方法的签名传递的,其中creator参数中有⇒ :
def apply[T <: Actor](creator: ? T)(implicit arg0: ClassTag[T]): Props
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
703 次 |
| 最近记录: |