Waitgroups in Kotlin
In Kotlin, we can use coroutines to achieve concurrent execution. To wait for multiple coroutines to finish, we can use a CountDownLatch
.
import kotlinx.coroutines.*
import java.util.concurrent.CountDownLatch
import kotlin.random.Random
// This is the function we'll run in every coroutine.
suspend fun worker(id: Int) {
println("Worker $id starting")
// Delay to simulate an expensive task.
delay(1000)
println("Worker $id done")
}
fun main() = runBlocking {
// This CountDownLatch is used to wait for all the
// coroutines launched here to finish.
val latch = CountDownLatch(5)
// Launch several coroutines and decrement the CountDownLatch
// counter for each.
repeat(5) { i ->
launch {
try {
worker(i + 1)
} finally {
latch.countDown()
}
}
}
// Block until the CountDownLatch counter goes back to 0;
// all the workers notified they're done.
latch.await()
// Note that this approach has no straightforward way
// to propagate errors from coroutines. For more
// advanced use cases, consider using structured concurrency
// with coroutineScope or supervisorScope.
}
To run the program:
$ kotlinc -cp kotlinx-coroutines-core-1.5.2.jar WaitGroups.kt -include-runtime -d WaitGroups.jar
$ java -jar WaitGroups.jar
Worker 3 starting
Worker 1 starting
Worker 5 starting
Worker 2 starting
Worker 4 starting
Worker 3 done
Worker 1 done
Worker 5 done
Worker 2 done
Worker 4 done
The order of workers starting up and finishing is likely to be different for each invocation.
In this Kotlin version:
We use coroutines instead of goroutines. Coroutines are Kotlin’s way of handling concurrent operations.
Instead of
WaitGroup
, we useCountDownLatch
. It serves a similar purpose of waiting for multiple operations to complete.The
worker
function is marked assuspend
to indicate it can be paused and resumed.We use
runBlocking
to create a coroutine scope that blocks the main thread until all coroutines complete.Instead of
go func()
, we uselaunch
to start new coroutines.We use
delay
instead oftime.Sleep
to pause execution without blocking the thread.Error handling in coroutines is typically done using structured concurrency with
coroutineScope
orsupervisorScope
, which provides more robust error propagation than this simple example.
This example demonstrates how to manage concurrent operations in Kotlin using coroutines and CountDownLatch
, achieving similar functionality to Go’s WaitGroups.