Title here
Summary here
In the previous example, we saw how to manage simple counter state using atomic operations. For more complex state, we can use a Mutex
to safely access data across multiple coroutines.
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
// Container holds a map of counters; since we want to
// update it concurrently from multiple coroutines, we
// add a Mutex to synchronize access.
// Note that in Kotlin, we don't need to worry about copying mutexes
// as we did in Go, because Kotlin objects are passed by reference.
class Container {
private val mu = Mutex()
private val counters = mutableMapOf("a" to 0, "b" to 0)
// Lock the mutex before accessing counters; unlock
// it at the end of the function using the withLock function.
suspend fun inc(name: String) = mu.withLock {
counters[name] = counters.getOrDefault(name, 0) + 1
}
fun getCounters(): Map<String, Int> = counters.toMap()
}
suspend fun main() = coroutineScope {
val c = Container()
// This function increments a named counter
// in a loop.
suspend fun doIncrement(name: String, n: Int) {
repeat(n) {
c.inc(name)
}
}
// Run several coroutines concurrently; note
// that they all access the same Container,
// and two of them access the same counter.
launch { doIncrement("a", 10000) }
launch { doIncrement("a", 10000) }
launch { doIncrement("b", 10000) }
// Wait for the coroutines to finish
// (This is implicitly done by coroutineScope)
println(c.getCounters())
}
Running the program shows that the counters updated as expected.
$ kotlinc -cp kotlinx-coroutines-core-1.5.2.jar mutexes.kt -include-runtime -d mutexes.jar
$ java -jar mutexes.jar
{a=20000, b=10000}
Next, we’ll look at implementing this same state management task using only coroutines and channels.
Note: This Kotlin version uses coroutines and the kotlinx.coroutines
library, which provides similar concurrency primitives to Go’s goroutines. The Mutex
is used from kotlinx.coroutines.sync
. You’ll need to include the kotlinx-coroutines library in your project to run this code.