Mutexes
Also known as mutual exclusions, mutexes provide a means to protect a shared state.
Let's start with same, old, dreaded counter example:
var counter = 0 val jobs = List(10) { launch { repeat(1000) { counter++ yield() } } } runBlocking { jobs.forEach { it.join() } println(counter) }
As you've probably guessed, this prints anything but the result of 10*100
. Totally embarrassing.
To solve that, we introduce a mutex:
var counter = 0 val mutex = Mutex() val jobs = List(10) { launch { repeat(1000) { mutex.lock() counter++ mutex.unlock() yield() } } }
Now our example always prints the correct number.
This is good for simple cases. But what if the code within the critical section (that is, between lock()
and unlock()
) throws an exception?
Then we'll have to wrap everything in try...catch
, which is not very convenient:
repeat(1000) { try { mutex.lock() counter++ } finally { mutex.unlock() } yield() }
Exactly...