您想查看 Scala 演员库或 Akka。 Akka 的语法更简洁,但两者都可以。
听起来您需要创建一个知道如何处理您的任务的参与者池。 Actor 基本上可以是任何具有接收方法的类 - 来自 Akka 教程 (http://doc.akkasource.org/tutorial-chat-server-scala):
class MyActor extends Actor {
def receive = {
case "test" => println("received test")
case _ => println("received unknown message")
}}
val myActor = Actor.actorOf[MyActor]
myActor.start
您需要创建一个参与者实例池并将您的任务作为消息发送给它们。这是一篇关于 Akka actor pooling 的帖子,可能会有所帮助:http://vasilrem.com/blog/software-development/flexible-load-balancing-with-akka-in-scala/
在您的情况下,每个任务一个参与者可能是合适的(参与者与线程相比非常轻量级,因此您可以在单个 VM 中拥有很多参与者),或者您可能需要在它们之间进行一些更复杂的负载平衡。
编辑:
使用上面的示例actor,向它发送消息就像这样简单:
myActor ! "test"
然后演员将“收到的测试”输出到标准输出。
消息可以是任何类型,当与 Scala 的模式匹配结合使用时,您将拥有一个强大的模式来构建灵活的并发应用程序。
一般来说,Akka 演员会在线程共享方面“做正确的事”,并且对于 OP 的需求,我想默认值是可以的。但如果需要,您可以将 actor 应使用的调度程序设置为以下几种类型之一:
* Thread-based
* Event-based
* Work-stealing
* HawtDispatch-based event-driven
为演员设置调度程序很简单:
class MyActor extends Actor {
self.dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("thread-pool-dispatch")
.withNewThreadPoolWithBoundedBlockingQueue(100)
.setCorePoolSize(10)
.setMaxPoolSize(10)
.setKeepAliveTimeInMillis(10000)
.build
}
见http://doc.akkasource.org/dispatchers-scala
通过这种方式,您可以限制线程池大小,但同样,原始用例可能会满足使用默认调度程序的 50K Akka Actor 实例,并且可以很好地并行化。
这实际上只是触及了 Akka 可以做的事情的表面。它为 Scala 语言带来了 Erlang 提供的很多东西。 Actor 可以监视其他 Actor 并重新启动它们,从而创建自我修复应用程序。 Akka 还提供软件事务内存和许多其他功能。它可以说是 Scala 的“杀手级应用”或“杀手级框架”。