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 doneThe 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
workerfunction is marked assuspendto indicate it can be paused and resumed.We use
runBlockingto create a coroutine scope that blocks the main thread until all coroutines complete.Instead of
go func(), we uselaunchto start new coroutines.We use
delayinstead oftime.Sleepto pause execution without blocking the thread.Error handling in coroutines is typically done using structured concurrency with
coroutineScopeorsupervisorScope, 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.