I'm trying to make sense of the blocking
construct. While it's not entirely clear how it internally works, the general idea I got was that as long as I used Scala's global thread-pool, wrapping my code with a blocking
context would make sure the thread-pool would create extra space for this job (as it's not CPU bound).
(1 to 1000).foreach { i =>
Future {
println(i)
Thread.sleep(100 * 1000)
}
}
will quickly show that only 8 jobs can simultaneously run, while
(1 to 1000).foreach { i =>
Future {
blocking {
println(i)
Thread.sleep(100 * 1000)
}
}
}
will show that now we have around 250 simultaneous jobs. Wow! What then caught me off-guard was that
(1 to 1000).foreach { i =>
Future {
println(i)
Thread.sleep(100 * 1000)
}
}
('a' to 'z').foreach { c =>
Future {
blocking {
println(c)
Thread.sleep(100 * 1000)
}
}
}
will again only show 8 simultaneous jobs -- the blocking jobs won't get executed right away.
Why is this? What really are the internal mechanics of the blocking
context?
blocking
only takes effect once you've entered the blocking context. Since you have 8 non-blocking futures running, it won't start any new futures, so they can't enter the blocking context. In other words, Scala doesn't "know" they're blocking until they start being executed.
You can think of the second snippet as working like this:
blocking
, so the implementation makes room for more futures.Whereas your last snippet works like this:
blocking
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With