Java Thread wait notify
Object 클래스의 동기 제어
final void wait()
- 다른 스레드는
notify()
또는notifyAll()
가 호출 때까지 스레드를 대기시킨다. - 동기화 영역에서 락을 풀고 Wait-Set영역 (공유객체별 존재)으로 이동시킨다.
- 다른 스레드는
final void wait(long timeout)
wait()
의 타임아웃 버전이다.
final void notify()
- 이 객체의 대기중의 thread를 1개 재개한다. 재개하는 재개 대상은 선택할 수 없다.
- Wait-Set 영역에 있는 쓰레드를 깨워서 실행할 수 있도록 한다.
notify()
는 랜덤이라 내가 원하는 애 말고 다른 애들을 깨울 수도 있다.
final void notifyAll()
- 이 객체의 대기중의 모든 thread를 재개한다.
- notifyAll()은 Wait-Set에 있는 전부를 깨운다.
- wait, notify, notifyAll 모두 동기화 영역에서만 실행 가능하다.
- Object 클래스에서 제공하는 메서드이다
package com.devkuma.basic.thread.wait;
public class ThreadA extends Thread {
// 해당 쓰레드가 실행되면 자기 자신의 모니터링 락을 획득
// 5번 반복하면서 0.5초씩 쉬면서 total에 값을 누적
// 그후에 notify()메소드를 호출하여 wiat하고 있는 쓰레드를 깨운다.
int total;
@Override
public void run() {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(i + "를 더합니다.");
total += i;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
public static void main(String[] args) {
// 쓰레드 A를 생성후에 start한다.
// 해당 쓰레드가 실행되면, 해당 쓰레드는 run 메소드 안에서 자신의 모니터링 락을 획득
ThreadA a = new ThreadA();
a.start();
// b에 대하여 동기화 블럭을 설정
// 만약 main 쓰레드가 아래의 블록을 위의 Thread보다 먼저 실행되었다면 wait를 하게 되면서 모니터링 락을 놓고 대기
synchronized (a) {
try {
// b.wait()메소드를 호출.
// 메인쓰레드는 정지
// ThreadA가 5번 값을 더한 후 notify를 호출하게 되면 wait에서 깨어남
System.out.println("b가 완료될때까지 기다립니다.");
a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 깨어난 후 결과를 출력
System.out.println("Total is: " + a.total);
}
}
}
최종 수정 : 2021-08-27