Scala – Akka演员,期货和封闭
我在
Akka docs中看到,从封闭的演员关闭变量是很危险的.
现在,我有两个演员,其中一个要求从第二个演员,并做一些结果.在下面的这个例子中,我已经放在一起,演员累加器从演员NumberGenerator检索数字,并将它们相加,并在路上报告总和. 这可以用至少两种不同的方式完成,因为这个例子显示了两个不同的接收函数(A和B).两者之间的区别在于A不会关闭柜台变量;而是等待一个整数并将其加起来,而B创建一个关闭计数器的未来,并且总和.这发生在一个匿名的演员,只是为了处理onSuccess,如果我明白了解如何工作. import com.esotericsoftware.minlog.Log import akka.actor.{Actor,Props} import akka.pattern.{ask,pipe} import akka.util.Timeout import akka.util.duration._ case object Start case object Request object ActorTest { var wake = 0 val accRef = Main.actorSystem.actorOf(Props[Accumulator],name = "accumulator") val genRef = Main.actorSystem.actorOf(Props[NumberGenerator],name = "generator") Log.info("ActorTest","Starting !") accRef ! Start } class Accumulator extends Actor { var counter = 0 implicit val timeout = Timeout(5 seconds) // A: WITHOUT CLOSURE def receive = { case Start => ask(ActorTest.genRef,Request).mapTo[Int] pipeTo self case x: Int => counter += x; Log.info("Accumulator","counter = " + counter); self ! Start } // B: WITH CLOSURE def receive = { case Start => ask(ActorTest.genRef,Request).mapTo[Int] onSuccess { case x: Int => counter += x; Log.info("Accumulator","counter = " + counter); self ! Start } } } class NumberGenerator extends Actor { val rand = new java.util.Random() def receive = { case Request => sender ! rand.nextInt(11)-5 } } 在这种情况下使用闭包是绝对邪恶的吗?当然,我可以使用一个AtomicInteger而不是一个Int,或者在一些使用netty的网络场景下,在threadsafe通道上发出一个写操作,但这不是我的观点. 有可能问可笑的是:未来的onSuccess是否可以在这个演员身上执行,而不是匿名的中间演员,而不是在接收功能中定义一个案例? 编辑 更清楚的是,我的问题是:有没有办法强制一系列期货与给定的演员一样运行? 解决方法
问题是onSuccess将运行在与演员接收的线程不同的线程中.您可以使用pipeTo方法,或使用
Agent.使反对AtomicInteger可以解决问题,但不是那么干净 – 就是打破了Actor模型.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |