To create a mutex, you only need to create an instance of the Mutex class:
var mutex = Mutex()
Once you have a mutex, you can use the suspending extension function withLock() that executes a lambda using a lock, shown as follows:
fun asyncIncrement(by: Int) = async {
for (i in 0 until by) {
mutex.withLock {
counter++
}
}
}
Here we don't set any context when calling async(), because we don't really care about the thread that is calling the function – it will work regardless.
This will guarantee that all the increments to counter are synchronized by allowing only one coroutine to hold the lock at a time, and suspending any other coroutine trying to get it. So, none of the increments in counter will be lost regardless of how many times it's called, shown as follows: