Blocking
Blocking is work that waits instead of computing. A waiting step holds its worker while it waits for something else.
blocking marks a waiting step
The step waits briefly and then gives 7. The awaited value is printed.
import scala.concurrent.{Future, Await, blocking}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
val work = Future {
blocking {
Thread.sleep(50)
7
}
}
println(Await.result(work, 5.seconds))A waiting step still joins a sum
The waiting step gives 10 and the quick step gives 20. Their sum is printed.
import scala.concurrent.{Future, Await, blocking}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
val slow = Future {
blocking {
Thread.sleep(50)
10
}
}
val fast = Future(20)
val total = for
a <- slow
b <- fast
yield a + b
println(Await.result(total, 5.seconds))Two waiting steps combine in order
Each waiting step gives one value. Sequence collects both values and their sum is printed.
import scala.concurrent.{Future, Await, blocking}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
val tasks = List(
Future { blocking { Thread.sleep(50); 5 } },
Future { blocking { Thread.sleep(50); 6 } }
)
val total = Future.sequence(tasks).map(values => values.sum)
println(Await.result(total, 5.seconds))Example
import scala.concurrent.{Future, Await, blocking}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
@main def main(): Unit =
val tasks = List(2, 3, 4).map(n =>
Future {
blocking {
Thread.sleep(20)
n * 10
}
}
)
val total = Future.sequence(tasks).map(values => values.sum)
println(Await.result(total, 5.seconds))Key points
- Blocking work: Blocking work is work that waits for an outside event such as a file or a network reply.
- Use scala.concurrent.blocking to mark a block of code as waiting work.
- Pool: A pool is a group of workers that share incoming tasks.
- Growth: When waiting work is marked, the pool may add workers so other tasks keep moving.
- Use blocking only around code that truly waits, not around plain computing.
In this example, each task marks a short wait as blocking and then gives ten times its number. Sequence collects 20, 30 and 40, and map sums them to 90.
Note
In Scala, blocking is a hint to the execution context, not a command that creates a worker by itself.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
What does blocking do in Scala?