Managing mutable state
The main concern (and nightmare fuel) when we deal with asynchronous code is how to handle mutable state. We covered how to reduce mutable state with a functional style in Chapter 3, Immutability - It's Important. But sometimes it is impossible to use a functional immutable style. Coroutines offer some alternatives to this problem.
In the following example, we'll use several coroutines to update a counter:
import kotlin.system.measureTimeMillis
suspend fun repeatInParallel(times: Int, block: suspend () -> Unit) {
val job = launch {
repeat(times) {
launch(coroutineContext) {
block()
}
}
}
job.join()
}
fun main(args: Array<String>) = runBlocking {
var counter = 0
val time = measureTimeMillis {
repeatInParallel(1_000_000) {
counter++
}
}
println("counter = $counter")
println("time = $time")
}On smaller numbers, counter is right, but once we start increasing the size, we'll...