728x90
반응형
1️⃣ 상황 설정
- 공유 객체 obj가 있음 → 모니터 포함
- 두 스레드: Thread A(생산자), Thread B(소비자)
- 목적: Thread A가 데이터를 생산하면 Thread B가 소비
2️⃣ 모니터 구조 그림
[Object obj]
┌──────────────┐
│ Monitor │
│ ┌────────┐ │
│ │ Lock │ │ ← 현재 락 소유 스레드
│ └────────┘ │
│ ┌────────┐ │
│ │ Wait Q │ │ ← wait() 호출 스레드 대기 큐
│ └────────┘ │
└──────────────┘
- Lock: 현재 객체의 모니터를 점유한 스레드
- Wait Q: wait() 호출로 대기 중인 스레드 목록
3️⃣ 실행 흐름 예제
class Shared {
private int value;
private boolean available = false;
public synchronized void produce(int val) {
while (available) { // 데이터 있으면 기다림
try { wait(); } catch (InterruptedException e) {}
}
value = val;
available = true;
notify(); // 소비자 깨움
}
public synchronized int consume() {
while (!available) { // 데이터 없으면 기다림
try { wait(); } catch (InterruptedException e) {}
}
available = false;
notify(); // 생산자 깨움
return value;
}
}
4️⃣ 스레드 흐름
4-1. Thread A (생산자)
- synchronized(obj) → 모니터 락 획득
- 데이터가 이미 있으면 wait() 호출 → 락 해제, Wait Q로 이동
- Wait Q에 들어간 Thread A → 대기 상태
4-2. Thread B (소비자)
- synchronized(obj) → 락 획득 가능 (Thread A는 락 해제했으므로)
- 데이터 사용 → available = false
- notify() 호출 → Wait Q에서 Thread A를 깨어나도록 알림
- Thread B 종료 → 락 해제
4-3. Thread A 깨어남
- Wait Q에서 깨어난 Thread A → 락 재획득 대기
- 락 획득 후 produce() 계속 실행
5️⃣ 그림으로 이해 (타임라인)
Time →
Thread A: |--synchronized-->|--wait()-->[Wait Q]
Thread B: |--synchronized-->|--consume()-->|--notify()-->[Thread A 깨어남]
Thread A: |--락 획득-->|--continue produce
- wait() → 대기 큐로 이동 + 락 해제
- notify() → 대기 큐에서 하나를 깨움
- 모든 동작은 모니터(락) 안에서 이루어짐 → 스레드 안전 보장
💡 핵심 요약
- 모니터 = 락 + wait 큐
- synchronized → 락 획득
- wait() → 락 해제, 대기 큐 이동
- notify() → 대기 큐 중 하나 깨어나 실행 준비
- 대기 스레드는 락 획득 후 실행 재개
728x90
반응형
'JAVA' 카테고리의 다른 글
[JAVA] 모니터(Monitor) (0) | 2025.10.01 |
---|---|
[JAVA] synchronized 블록 (0) | 2025.09.29 |
[JAVA] Object.wait() (0) | 2025.09.25 |
[JAVA] Thread.sleep() (0) | 2025.09.24 |
[JAVA] String 배열 초기화 (0) | 2025.07.21 |