Channel Synchronization in Scala
We can use channels to synchronize execution across threads. Here’s an example of using a blocking receive to wait for a thread to finish. When waiting for multiple threads to finish, you may prefer to use a CountDownLatch
or Future
.
import scala.concurrent.{Future, Await}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
object ChannelSynchronization {
// This is the function we'll run in a separate thread. The
// `done` promise will be used to notify another thread
// that this function's work is done.
def worker(done: scala.concurrent.Promise[Boolean]): Unit = {
print("working...")
Thread.sleep(1000) // Simulate work
println("done")
// Complete the promise to notify that we're done.
done.success(true)
}
def main(args: Array[String]): Unit = {
// Create a promise to be completed when the work is done
val done = scala.concurrent.Promise[Boolean]()
// Start a worker thread, giving it the promise to complete
Future {
worker(done)
}
// Block until we receive a notification from the
// worker on the Future
Await.result(done.future, Duration.Inf)
}
}
To run the program:
$ scala ChannelSynchronization.scala
working...done
If you removed the Await.result(done.future, Duration.Inf)
line from this program, the program would exit before the worker
even started.
In this Scala version:
We use a
Promise
and its associatedFuture
instead of a channel. APromise
in Scala is somewhat similar to a single-use channel in Go.The
worker
function takes aPromise[Boolean]
instead of a channel. It completes the promise when the work is done.In the
main
function, we create aPromise
and pass it to a newFuture
that runs theworker
.We use
Await.result
to block until theFuture
completes, which is analogous to receiving from a channel in the Go version.We use
Thread.sleep
instead oftime.Sleep
to simulate work being done.
This example demonstrates how to use Scala’s concurrency primitives to achieve similar synchronization behavior to Go’s channels.