1

I create 10000 actors and send a message to each, but it seems that the akka system can't complete all the work. when I check the thread state, they are all in TIMED_WATIING.

My code:

class Reciver extends Actor {
  val log = Logging(context.system, this)
  var num = 0

  def receive = {
    case a: Int => log.info(s"[${self.path}] receive $a, num is $num")
      Thread.sleep(2000)
      log.info(s"[${self.path}] processing $a, num is $num")
      num = a
  }
}

object ActorSyncOrAsync extends App {
  val system = ActorSystem("mysys")

  for (i <- 0 to 10000) {
    val actor = system.actorOf(Props[Reciver])
    actor ! i
  }
  println("main thread send request complete")
}
SiHa
  • 7,830
  • 13
  • 34
  • 43
john
  • 67
  • 3

1 Answers1

3

You should remove Thread.sleep or (if you're using default thread-pool) surround it with:

scala.concurrent.blocking { 
  Thread.sleep(2000)
}

scala.concurrent.blocking marks the computation to have a managed blocking, which means that it tells the pool that computation is not taking CPU resources but just waits for some result or timeout. You should be careful with this however. So, basically, this advice works if you're using Thread.sleep for debugging purposes or just to emulate some activity - no Thread.sleep (even surrounded by blocking) should take place in production code.

Explanation:

When some fixed pool is used (including fork-join as it doesn't steal work from threads blocked by Thread.sleep) - there is only POOL_SIZE threads (it equals to the number of cores in your system by default) is used for computation. Everything else is going to be queued.

So, let's say 4 cores, 2 seconds per task, 10000 tasks - it's gonna take 2*10000/4 = 5000 seconds.

The general advice is to not block (including Thread.sleep) inside your actors: Blocking needs careful management. If you need to delay some action it's better to use Scheduler (as @Lukasz mentioned): http://doc.akka.io/docs/akka/2.4.4/scala/scheduler.html

dk14
  • 22,206
  • 4
  • 51
  • 88
  • He probably just should use scheduler to perform the part of processing message after sleep and remove sleep altogether. – Łukasz Oct 29 '16 at 07:15
  • @Lukasz I believe Thread.sleep was just for debugging purposes, but I'll add this info to the answer as well. Thanks! – dk14 Oct 29 '16 at 07:16