JAVA

[JAVA] Object.wait()

오선지♬ 2025. 9. 25. 10:56
728x90
반응형

Java에서 wait()는 모든 객체에 있는 메서드라는 점을 기억해야 합니다. 즉, Object 클래스에 정의되어 있어서 모든 객체에서 호출 가능합니다. 하지만 단순히 obj.wait()라고 하면 조금 복잡한 동작 원리가 있어요.

 

1️⃣ 기본 개념

  • 목적: 스레드를 일시 정지시키고, 다른 스레드가 해당 객체의 상태를 변경할 때까지 기다리게 하는 것.
  • 위치: java.lang.Object 클래스에 정의됨.
  • 조건: wait()를 호출할 때, 반드시 해당 객체의 모니터(락)을 소유하고 있어야 함 (즉, synchronized 블록 안에서만 호출 가능).
 
synchronized(obj) {
    obj.wait();  // obj의 모니터를 가지고 있어야 함
}

2️⃣ 주요 특징

특징 설명
모니터 필요 wait()는 반드시 synchronized 블록 안에서 호출해야 함
일시 정지 호출한 스레드를 멈추고, 다른 스레드가 notify() 또는 notifyAll() 호출할 때까지 기다림
자동 락 해제 wait() 호출 시 해당 객체의 락을 자동으로 해제하고, 다시 깨어날 때 락을 재획득
예외 InterruptedException이 발생할 수 있음 (다른 스레드가 인터럽트하면 깨어남)

3️⃣ 메서드 오버로드

 
void wait() throws InterruptedException
void wait(long timeout) throws InterruptedException
void wait(long timeout, int nanos) throws InterruptedException
  • wait() : 무한정 기다림, notify()나 notifyAll() 호출될 때까지.
  • wait(timeout) : 지정 시간(ms) 동안만 기다림. 시간이 지나면 자동으로 깨어남.
  • wait(timeout, nanos) : 밀리초 + 나노초 단위로 기다림.

4️⃣ 사용 예제

 
class Data {
    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;
    }
}

public class WaitNotifyExample {
    public static void main(String[] args) {
        Data data = new Data();

        // Producer
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                data.produce(i);
                System.out.println("Produced: " + i);
            }
        }).start();

        // Consumer
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                int val = data.consume();
                System.out.println("Consumed: " + val);
            }
        }).start();
    }
}
  • 생산자(Producer)는 값이 이미 있으면 기다림(wait()).
  • 소비자(Consumer)는 값이 없으면 기다림(wait()).
  • 값이 준비되면 notify()로 상대 스레드를 깨움.

💡 정리:

  1. Object.wait()는 스레드를 일시 정지시키는 메서드.
  2. 반드시 synchronized 블록 안에서 호출.
  3. notify() 또는 notifyAll()에 의해 깨어나거나, 지정 시간(timeout) 후 자동 깨어남.
  4. 락을 자동 해제 → 다른 스레드가 해당 객체를 사용할 수 있음.
728x90
반응형

'JAVA' 카테고리의 다른 글

[JAVA] 모니터(Monitor)  (0) 2025.10.01
[JAVA] synchronized 블록  (0) 2025.09.29
[JAVA] Thread.sleep()  (0) 2025.09.24
[JAVA] String 배열 초기화  (0) 2025.07.21
[JAVA] Stream보다 forEach가 더 나은 경우  (0) 2025.05.10