[kotlin] 코틀린에서의 뮤텍스와 세마포어 활용하기

뮤텍스와 세마포어는 동시성 프로그래밍에서 많이 사용되는 개념입니다. Kotlin에서도 뮤텍스와 세마포어를 활용하여 스레드 간의 상호작용을 조절할 수 있습니다. 이번 포스트에서는 Kotlin에서 뮤텍스와 세마포어를 어떻게 활용하는지 알아보겠습니다.

뮤텍스(Mutex)

뮤텍스는 상호배제 기능을 제공하는 동기화 기법 중 하나로, 한 번에 하나의 스레드만이 공유 자원에 접근할 수 있도록 제어하는 것을 말합니다. Kotlin에서는 Mutex 클래스를 제공하여 뮤텍스를 사용할 수 있습니다.

다음은 Kotlin에서 뮤텍스를 활용하는 예제 코드입니다.

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

val mutex = Mutex()
var sharedResource = 0

fun main() = runBlocking {
    launch {
        repeat(100) {
            mutex.withLock {
                sharedResource++
            }
        }
    }
    launch {
        repeat(100) {
            mutex.withLock {
                sharedResource--
            }
        }
    }
    delay(1000)
    println("Final value of sharedResource: $sharedResource")
}

위의 코드는 Mutex를 사용하여 sharedResource 변수에 대한 접근을 동기화하는 예제입니다. mutex.withLock 블록을 사용하여 뮤텍스를 획득한 후에만 sharedResource 변수에 접근할 수 있습니다.

세마포어(Semaphore)

세마포어는 한 번에 여러 개의 스레드가 공유 자원에 접근할 수 있는 동기화 기법입니다. Kotlin에서는 Semaphore 클래스를 제공하여 세마포어를 사용할 수 있습니다.

다음은 Kotlin에서 세마포어를 활용하는 예제 코드입니다.

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Semaphore

val semaphore = Semaphore(3)
var sharedResource = 0

fun main() = runBlocking {
    repeat(10) {
        launch {
            semaphore.acquire()
            try {
                sharedResource++
                delay(1000)
                println("Shared resource is updated: $sharedResource")
            } finally {
                semaphore.release()
            }
        }
    }
    delay(5000)
    println("Final value of sharedResource: $sharedResource")
}

위의 코드는 Semaphore를 사용하여 sharedResource 변수에 대한 접근을 제어하는 예제입니다. semaphore.acquire()를 호출하여 세마포어를 획득한 후에만 sharedResource 변수에 접근할 수 있습니다. semaphore.release()를 호출하여 세마포어를 해제합니다.

결론

이번 포스트에서는 Kotlin에서 뮤텍스와 세마포어를 활용하는 방법을 알아보았습니다. 뮤텍스는 한 번에 하나의 스레드만이 공유 자원에 접근할 수 있도록 제어하고, 세마포어는 여러 개의 스레드가 공유 자원에 접근할 수 있도록 제어합니다. 이러한 동기화 기법을 적절히 활용하면 동시성 프로그래밍에서 발생할 수 있는 문제를 효과적으로 해결할 수 있습니다.

참고 자료