Для (1) у вас есть гарантия, что диспетчер msg1 будет поставлен в очередь перед msg2.То, что происходит на самом деле, когда они ставятся в очередь, действительно зависит от того, какой диспетчер вы используете: http://akka.io/docs/akka/1.1.2/scala/dispatchers.html,, но в вашем случае, если B может принять оба сообщения, он всегда будет получать msg1 до msg2.
Для (2), нет, у вас нет этой гарантии.!Метод возвращается, как только диспетчер ставит сообщение в очередь, а не когда сообщение принимается почтовым ящиком целевого субъекта.Затем отправка выполняется в другом потоке и зависит от всех условий гонки.
Является ли сообщение, отправленное!оператор через сеть действительно асинхронный или он ждет, пока получающий почтовый ящик не получит его?
Вы можете использовать BoundedMailbox с локальными субъектами, чтобы показать, что постановка в очередь сообщений диспетчерам асинхронна с!:
class TestActor extends Actor {
val mailboxCapacity = BoundedMailbox(capacity = 1)
self.dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("test", 1, mailboxCapacity).build
def receive = {
case x: String =>
Thread.sleep(1000)
println("Received message")
case _ =>
}
}
val t = Actor.actorOf[TestActor]
t.start()
t ! "one"; t ! "two"; t ! "three"; println("Main thread");
Отпечатки:
scala> t ! "one"; t ! "two"; t ! "three"; println("Main thread");
Received message
Main thread
scala> Received message
Received message
Это означает, что выполнение кода в главном потоке продолжается до того, как вы узнаете, будет ли доставлено сообщение.В этом случае отправка сообщения могла легко истечь, если мы установили pushTimeout на диспетчере и заставили Thread.sleep ждать дольше, чем время ожидания.
Сравните это с использованием !!:
scala> t !! "one"; t !! "two"; t !! "three"; println("test");
Received message
Received message
Received message
test
Итак, помните об этом.Способ достижения (2) будет:
case msg1 =>
cRef !! msg3
aRef ! msg4