Akka上下文变为保持州秩序

时间:2015-05-13 09:03:52

标签: scala akka mutable

我有以下简单的Actor:

class MutableStateActor extends Actor with ActorLogging {

  var counter = 0

  val increment = (x: Int) => {
    counter = counter + 1
    s"$counter"
  }

  def receive = {
    case _ => context.become(mutableReceiver)
  }

  def mutableReceiver: Receive = {
    case Increment => {
      Future { println(s"counter in Increment is ${increment(counter)}"); self ! CounterStatus }
      //println(s"counter in Increment is ${increment(counter)}"); self ! CounterStatus
    }
    case CounterStatus => {
      println(counter)
    }
  }
}
object MutableStateActor {
  case class Increment()
  case class CounterStatus()
}

当我使用以下测试进行测试时:

  "A MutableStateActor" must {

    val actorRef = system.actorOf(Props[MutableStateActor])

    "mutate state in order" in {
      1 to 5 foreach {
        x => actorRef ! Increment
      }
    }
  }

我可以看到保存计数器递增的顺序。我明白了:

counter in Increment is 1
counter in Increment is 2
counter in Increment is 3
counter in Increment is 4
4
4
4
4

如果我在我的演员中改变我的接收方法而不做上下文。成为:

 def receive: Receive = {
    case Increment => {
      Future { println(s"counter in Increment is ${increment(counter)}"); self ! CounterStatus }
      //println(s"counter in Increment is ${increment(counter)}"); self ! CounterStatus
    }
    case CounterStatus => {
      println(counter)
    }
  }

我得到一个关于计数器增量的非确定性行为。

counter in Increment is 2
counter in Increment is 4
counter in Increment is 1
counter in Increment is 3
counter in Increment is 5
5
5
5
5
5

1 个答案:

答案 0 :(得分:0)

在第一种情况下,println在解析Future时执行,并按创建顺序解析。

在第二种情况下,println在一个线程中执行,然后返回Future,因此,线程执行的顺序是不确定的。