Akka docs에서 액세사리의 변수를 닫는 것이 위험합니다. 주의 깊게 익명 Actor 클래스 내에서 둘러싸는 배우의 메소드를 호출하지 마십시오 포함하는 배우의 참조를 통해 폐쇄 즉를 방지하기 위해 필요한이 경우Akka 배우, 선물 및 종결
경고
. 그러면 은 액터 캡슐화를 깨고 동기화 비트와 경합 조건을 야기 할 수 있습니다. 다른 액터의 코드는 동봉 액터와 동시에 으로 예약 될 것이기 때문입니다.
저는 두 명의 액터가 있습니다. 그 중 하나는 두 번째 액터에서 뭔가를 요청하고 그 결과로 무언가를합니다. 아래 예제에서 나는 함께 배우를 넣었습니다 누산기은 NumberGenerator의 숫자를 검색하여 합계를보고하면서 합계를보고합니다. 다른 는 함수 (을 B VS) 개의 수신이 예와 같이
이 적어도 두 가지 방법으로 수행 될 수있다. 두 가지의 차이점은 은 카운터 변수를 닫지 않습니다. 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
}
}
이 경우 클로저를 사용하는 것은 완전히 위험합니까? 물론 Int 대신 AtomicInteger를 사용하거나 netty을 사용하는 일부 네트워킹 시나리오에서는 threadsafe 채널에서 쓰기 작업을 수행 할 수 있지만 여기에는 내 요점이 없습니다. 말도 안되는 요청의 위험
는 : 대신 익명의 중간 배우의 이 배우를 실행 경우를 정의없이 할 수있는 미래의는 onSuccess위한 방법이 수신 기능인가?
편집
더 명확하게 말하면, 내 질문은 : 주어진 배우와 같은 스레드에서 실행하는 선물의 시리즈를 강제 할 수있는 방법이 있습니까?
+1 상담원의 사용을 제안합니다. – gsimard