Java

wait(), notify()

1space 2025. 6. 28. 14:01

자바의 정석[기초편]으로 공부한 내용을 정리한 글입니다.

핵심 요약

  • wait()와 notify()는 동기화된 블록(synchronized) 안에서만 사용할 수 있고, Object 클래스에 정의되어 있습니다.
  • wait()는 현재 쓰레드가 객체의 락(lock)을 풀고, waiting pool에 들어가 기다립니다.
  • notify()는 waiting pool에서 하나의 쓰레드를 깨웁니다.
  • notifyAll()은 모든 대기 중인 쓰레드를 깨웁니다.
synchronized void withdraw(int money) {
    while(balance < money) {
        wait();  // 잔액 부족 -> 대기
    }
    balance -= money;  // 출금
}
  • 출금하려 했으나 잔액 부족하면 기다립니다 (wait()로 lock 풀고 waiting pool 대기)
  • 다른 쓰레드가 deposit()을 호출하면, 돈이 입금되고 notify() 호출 → 출금 쓰레드를 깨움

 

예제1  – 요리사와 손님 (동기화 X)

구조 설명

  • Table이라는 객체를 공유함: 요리사는 Table에 음식을 add(), 손님은 Table에서 음식을 remove()
  • ArrayList로 구현되어 있고, 동기화 안된 상태
if (dishes.size() >= MAX_FOOD) return;
dishes.add(dish);  // 요리사
...
table.remove(food);  // 손님

 

실행 결과 (동기화 X)

문제 발생

  • 두 쓰레드가 동시에 ArrayList를 수정하다 보니 ConcurrentModificationException 발생
  • 또는 한 손님이 남은 음식 먹으려는 순간 다른 손님이 먼저 먹어서 IndexOutOfBoundsException

원인

  • ArrayList는 쓰레드에 안전하지 않음 (동기화 필요)
  • 쓰레드 간 작업 충돌 발생

 

예제1 개선 (동기화 O)

해결 방법

  • add()와 remove()를 synchronized로 감싸서 동기화
public synchronized void add(String dish) { ... }
public boolean remove(...) {
    synchronized(this) {
        while (dishes.size() == 0) { ... }
    }
}

이로써 충돌은 사라지지만, 효율성 문제는 여전

 

실행 결과 (동기화 O)

문제점

  • 예외는 발생하지 않지만, lock을 너무 오래 점유하는 문제가 발생
  • 예: 손님이 음식이 없는데도 계속 Table의 lock을 잡고 있으니 요리사는 접근 못함

 

예제2 - wait()와 notify() 적용

문제 해결

  • 손님은 음식이 없으면 wait()으로 lock을 풀고 대기
  • 요리사가 음식 추가하면 notify()로 손님을 깨움
// 요리사
synchronized void add(...) {
    while (dishes.size() >= MAX_FOOD) wait();  // 가득 찼으면 대기
    dishes.add(...);
    notify();  // 손님 깨움
}

// 손님
synchronized void remove(...) {
    while (dishes.size() == 0) wait();  // 음식 없으면 대기
    dishes.remove(...);
    notify();  // 요리사 깨움
}

 

예제2 실행 결과

결과

  • 요리사와 손님이 서로 lock을 오래 잡는 일이 사라짐
  • 누군가 기다려야 할 상황이면 wait()로 lock을 양보하고, 조건이 충족되면 notify()로 정확하게 깨움
  • 시스템이 효율적으로 돌아감 (lock 효율 ↑)

 

전체 정리하면:

상황 문제 해결책
여러 스레드가 ArrayList 공유 충돌 발생 synchronized로 동기화
한 스레드가 lock을 오래 점유 효율성 ↓ wait()과 notify()로 조건 충족 시 알림

'Java' 카테고리의 다른 글

함수형 인터페이스  (0) 2025.06.28
람다식이란?  (0) 2025.06.28
쓰레드 동기화  (0) 2025.06.27
join(), yield()  (0) 2025.06.27
suspend(), resume()  (0) 2025.06.27