Reputation: 95
I know that scala.concurrent.blocking is a hint for ExecutionContext that a piece of code performs some long operation / blocks on some IO. ExecutionContext can, but does not have to, make use of this "hint".
As described here:
scala.concurrent.blocking - what does it actually do?
http://www.cakesolutions.net/teamblogs/demystifying-the-blocking-construct-in-scala-futures
scala.concurrent.ExecutionContext.Implicits.global is a ForkJoinPool, which spawns a new thread for a code wrapped in scala.concurrent.blocking.
What about Akka's fork-join-executor. Does it also make use of scala.concurrent.blocking in any way?
Upvotes: 3
Views: 536
Reputation: 55569
Yes, it does!
It's easy enough to figure this out by searching for BlockContext
. For Akka, that leads us here, and if you follow the threads in the code and documentation, you can confirm it.
This is also easy enough to test on our own. We can make a new ActorSystem
without any configured dispatchers (so it will use the default fork-join-executor), then use its dispatcher as our ExecutionContext
.
import akka.actor._
import scala.concurrent._
implicit val ec = ActorSystem("test").dispatcher
First, without blocking you will notice that several futures start right away, but not all of them. The another batch will start as the first batch completes. Clearly, the default pool reaches starvation:
(0 to 100) foreach { n =>
Future {
println("starting Future: " + n)
Thread.sleep(3000)
println("ending Future: " + n)
}
}
Then, with blocking
all of the futures should execute almost immediately, as opposed to the previous example:
(0 to 100) foreach { n =>
Future {
println("starting Future: " + n)
blocking(Thread.sleep(3000))
println("ending Future: " + n)
}
}
Upvotes: 2