개요
- Mutual Exclusion / 상호배제는 공유 자원에 대한 경쟁 상태를 방지하고 동시성 제어를 위한 ["락/Lock"] 매커니즘이다.
- 스레드가 임계영역에서 Mutex 객체의 플래그를 소유하고 있으면 (락 획득) 다른 스레드가 액세스할 수 없으며 해당 임계 영역에 액세스 하려고 시도하는 모든 스레드는 차단된다. Mutex 객체 플래그가 해제된 경우 (락 해제)에만 액세스할 수 있다.
- Mutex 락을 가진 오직 한개의 스레드만이 임계영역에 진입할 수 있고 락을 획득한 스레드만이 락을 해제할 수 있다.
Mutext
- 뮤텍스는 락/락 해제를 통해 자원을 보호하는 락체계 동기화 도구이다.
문제점
- 데드락
- 데드락은 두 개 이상의 스레드가 서로가 가진 락을 기다리면서 상호적으로 블로킹 되는 경우.
- 이로 인해 아무 작업도 수행할 수 없는 상태를 의미하고 잘못된 뮤텍스 사용으로 인해 데드락이 발생할 수 있다.
- 우선 순위 역전
- 높은 우선 순위를 가진 스레드가 낮은 우선순위를 가진 스레드가 보유한 락을 기다리는 동안 블록되는 현상.
- T1 > T2 > T3 우선순위일 때, T1이 T3를 기다리느라 T2가 먼저 완료되는 현상.
- T2가 우선 순위가 낮음에도 더 빨리 수행되는 역전이 발생한다.
- 우선 순위 상속으로 해결할 수 있다. T1의 우선순위를 T3에 상속해주면 됨.
- 높은 우선 순위를 가진 스레드가 낮은 우선순위를 가진 스레드가 보유한 락을 기다리는 동안 블록되는 현상.
- 오버헤드
- 여러 스레드가 경합하면서 락을 얻기 위해 스레드 스케쥴링이 발생하는 것.
- 성능 저하
- 뮤텍스을 사용하면 락을 얻기 위해 대기하게 되는데, 이로 인해 스레드의 실행시간이 블로킹되면서 성능저하가 발생하는 것.
- 잘못된 사용
- 뮤텍스를 적절하게 사용하지 않거나 잘못된 순서로 락을 해제하는 경우 예상치 못한 동작이 발생할 수 있음.
Mutex Lock을 직접 만들어서 테스트
/* 동기화를 위한 락 체계 */
class Mutex {
private var lock = false
@Synchronized
fun acquire() {
while (lock) {
try {
(this as Object).wait()
} catch (e: InterruptedException) {
throw RuntimeException(e)
}
}
lock = true
}
@Synchronized
fun release() {
lock = false
(this as Object).notify()
}
}
/* 공유자원 */
class SharedData {
private var counter = 0
private var mutex: Mutex
constructor(mutex: Mutex) {
this.mutex = mutex
}
fun sum() {
try {
mutex.acquire() // <--------- 핵심
for (i in 0 until 10000) {
counter++
}
} finally {
mutex.release()
}
}
fun getCounter(): Int {
return counter
}
}
실행 로직
fun main() {
val mutex = Mutex()
val sharedData = SharedData(mutex)
val thread1 = Thread {
sharedData.sum()
}
val thread2 = Thread {
sharedData.sum()
}
thread1.start()
thread2.start()
thread1.join()
thread2.join()
println("Final Counter: ${sharedData.getCounter()}")
}


두 스레드가 하나의 공유자원에 대해 카운트 업데이트를 시도하고 있다. Mutex Lock을 통해 동시성을 제어할 수 있다.
acquire 로직을 주석 처리 시 동시성 이슈가 발생함을 볼 수 있다.
반응형
'기술 학습 > JVM 스레드 딥다이브' 카테고리의 다른 글
| JVM 동시성 프로그래밍 딥다이브 5. Synchronization Fundamentals 동기화 개념 - 싱글/멀티 스레드 & 동기화 (0) | 2026.02.15 |
|---|---|
| JVM 동시성 프로그래밍 딥다이브 4-2. 스레드 활용 - ThreadLocal (0) | 2026.02.01 |
| JVM 동시성 프로그래밍 딥다이브 4-1. 스레드 활용 - 예외처리, 유저/데몬 스레드, ThreadGroup (0) | 2026.01.18 |
| JVM 동시성 프로그래밍 딥다이브 3. 스레드 기본 API - Sleep, Join, Interrupt 등 (1) | 2026.01.04 |
| JVM 동시성 프로그래밍 딥다이브 2. 스레드 생명주기와 상태 (0) | 2025.12.21 |