我正在评估Akka的分布式服务层,以下示例打印Hello {n} 10次,但是一个接一个地打印。根据我的理解,这是一个Akka演员的故意,所以我从哪里开始使其并发?
import akka.actor._
object HelloActor {
case class SayHello(message: String)
}
class HelloActor extends Actor {
def receive = {
case HelloActor.SayHello(message) =>
Thread.sleep(1000)
println(message)
}
}
object Main extends App {
val system = ActorSystem("ActorSystem")
val hello = system.actorOf(Props[HelloActor])
for (i <- 1 to 10) {
hello ! HelloActor.SayHello(s"Hello $i")
}
}
我已经尝试过从Main类创建多个actor但是在某种程度上感觉不对,我不应该只调用actor然后它自己处理并发/产生更多的actor吗?任何人都可以提供一个这样的例子(最好是修改上面的代码)。我一直在阅读和阅读,但立刻感觉很多,我觉得我在某处错过了一个关键概念。
答案 0 :(得分:4)
对于您的用例,您可能希望使用Routers。
例如:
val hello = system.actorOf(Props[HelloActor].withRouter(
RoundRobinRouter(nrOfInstances = 10)))
hello ! HelloActor.SayHello("Hello!") // Sends to one of the 10
作为旁注,你应该避免在你的演员的Thread.sleep
方法中阻止(即receive
)。
答案 1 :(得分:1)
正如@sourcedelica在评论中提到的,路由可能就是你想要做的。使用RoundRobinRouter
的示例的简单重构可能如下所示:
import akka.actor._
import akka.routing._
object HelloActor {
case class SayHello
}
class HelloActor extends Actor {
def receive = {
case HelloActor.SayHello =>
println(s"saying hello from: ${self.path}")
}
}
object Main extends App {
val system = ActorSystem("ActorSystem")
val hello = system.actorOf(Props[HelloActor].withRouter(RoundRobinRouter(10)))
for (i <- 1 to 10) {
hello ! HelloActor.SayHello
}
}
这是一个非常简单的例子,因为它使用的是简单的路由器(循环法)并且它没有调整大小。您可以使用路由器做更多事情,我强烈建议您更多地阅读它们: