How can I execute multiple tasks in Scala?

后端 未结 4 1104
挽巷
挽巷 2021-01-30 04:33

I have 50,000 tasks and want to execute them with 10 threads. In Java I should create Executers.threadPool(10) and pass runnable to is then wait to process all. Scala as I under

4条回答
  •  失恋的感觉
    2021-01-30 04:46

    You want to look at either the Scala actors library or Akka. Akka has cleaner syntax, but either will do the trick.

    So it sounds like you need to create a pool of actors that know how to process your tasks. An Actor can basically be any class with a receive method - from the Akka tutorial (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
    

    You'll want to create a pool of actor instances and fire your tasks to them as messages. Here's a post on Akka actor pooling that may be helpful: http://vasilrem.com/blog/software-development/flexible-load-balancing-with-akka-in-scala/

    In your case, one actor per task may be appropriate (actors are extremely lightweight compared to threads so you can have a LOT of them in a single VM), or you might need some more sophisticated load balancing between them.

    EDIT: Using the example actor above, sending it a message is as easy as this:

    myActor ! "test"
    

    The actor will then output "received test" to standard output.

    Messages can be of any type, and when combined with Scala's pattern matching, you have a powerful pattern for building flexible concurrent applications.

    In general Akka actors will "do the right thing" in terms of thread sharing, and for the OP's needs, I imagine the defaults are fine. But if you need to, you can set the dispatcher the actor should use to one of several types:

    * Thread-based
    * Event-based
    * Work-stealing
    * HawtDispatch-based event-driven
    

    It's trivial to set a dispatcher for an actor:

    class MyActor extends Actor {
      self.dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("thread-pool-dispatch")
        .withNewThreadPoolWithBoundedBlockingQueue(100)
        .setCorePoolSize(10)
        .setMaxPoolSize(10)
        .setKeepAliveTimeInMillis(10000)
        .build
    }
    

    See http://doc.akkasource.org/dispatchers-scala

    In this way, you could limit the thread pool size, but again, the original use case could probably be satisfied with 50K Akka actor instances using default dispatchers and it would parallelize nicely.

    This really only scratches the surface of what Akka can do. It brings a lot of what Erlang offers to the Scala language. Actors can monitor other actors and restart them, creating self-healing applications. Akka also provides Software Transactional Memory and many other features. It's arguably the "killer app" or "killer framework" for Scala.

提交回复
热议问题