JAVA

[JAVA] 스레드와 wait()와 notify() 상호작용

오선지♬ 2025. 10. 2. 12:30
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 (생산자)

  1. synchronized(obj) → 모니터 락 획득
  2. 데이터가 이미 있으면 wait() 호출 → 락 해제, Wait Q로 이동
  3. Wait Q에 들어간 Thread A → 대기 상태

4-2. Thread B (소비자)

  1. synchronized(obj) → 락 획득 가능 (Thread A는 락 해제했으므로)
  2. 데이터 사용 → available = false
  3. notify() 호출 → Wait Q에서 Thread A를 깨어나도록 알림
  4. Thread B 종료 → 락 해제

4-3. Thread A 깨어남

  1. Wait Q에서 깨어난 Thread A → 락 재획득 대기
  2. 락 획득 후 produce() 계속 실행

5️⃣ 그림으로 이해 (타임라인)

 
Time →
Thread A: |--synchronized-->|--wait()-->[Wait Q]
Thread B:        |--synchronized-->|--consume()-->|--notify()-->[Thread A 깨어남]
Thread A:                              |--락 획득-->|--continue produce
  • wait() → 대기 큐로 이동 + 락 해제
  • notify() → 대기 큐에서 하나를 깨움
  • 모든 동작은 모니터(락) 안에서 이루어짐 → 스레드 안전 보장

💡 핵심 요약

  1. 모니터 = 락 + wait 큐
  2. synchronized → 락 획득
  3. wait() → 락 해제, 대기 큐 이동
  4. notify() → 대기 큐 중 하나 깨어나 실행 준비
  5. 대기 스레드는 락 획득 후 실행 재개
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