뮤텍스와 세마포어는 동시성 프로그래밍에서 많이 사용되는 개념입니다. 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에서 뮤텍스와 세마포어를 활용하는 방법을 알아보았습니다. 뮤텍스는 한 번에 하나의 스레드만이 공유 자원에 접근할 수 있도록 제어하고, 세마포어는 여러 개의 스레드가 공유 자원에 접근할 수 있도록 제어합니다. 이러한 동기화 기법을 적절히 활용하면 동시성 프로그래밍에서 발생할 수 있는 문제를 효과적으로 해결할 수 있습니다.
참고 자료
- Kotlin Coroutines 공식 문서: https://kotlinlang.org/docs/reference/coroutines-overview.html
- Java Concurrency in Practice 책: Brian Goetz 등 저, Addison-Wesley Professional, 2006