🎓 A1Learner
🔍
0 of 45 lessons completed

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?