Sobes.tech
Middle+

Kuidas töötab mutex korutinites?

sobes.tech AI

Vastus AI-lt

Mutex in coroutines provides a mutual exclusion mechanism to protect shared resources from concurrent access by multiple coroutines.

Working principle:

  1. Acquiring the mutex: The coroutine that wants to access the protected resource calls the lock() method.
  2. Locking: If the mutex is free, the coroutine acquires it non-blockingly and continues execution. If the mutex is occupied by another coroutine, the calling coroutine suspends until the mutex is released.
  3. Releasing the mutex: After finishing work with the protected resource, the coroutine calls the unlock() method to release the mutex.

Key features in coroutines:

  • Non-blocking lock() (when the mutex is free): Unlike traditional threads where lock() can block the entire thread, in coroutines, if the mutex is free, the acquisition occurs non-blockingly.
  • Suspension of coroutine (when the mutex is busy): If the mutex is busy, the calling coroutine does not block the thread but suspends until it is released. This frees the thread for other coroutines.
  • withLock extension function: A convenient way to use the mutex that automatically acquires and releases it, even if an exception occurs inside the block.

Example usage:

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex

val mutex = Mutex()
var counter = 0

suspend fun incrementCounter() {
    mutex.withLock {
        // Critical section - protected resource
        counter++
        delay(10) // Simulate work
        println("Counter: $counter")
    } // Mutex is automatically released here
}

fun main() = runBlocking {
    repeat(100) {
        launch {
            incrementCounter()
        }
    }
    delay(1000)
}

In this example, incrementCounter is a critical section that modifies the shared resource counter. The mutex ensures that only one coroutine at a time has access to this section, preventing race conditions. Using withLock simplifies mutex management.