wait () 실행 후 스레드가 다른 스레드로부터 알림을받지 못하면 얼마나 오래 대기합니까?

Aug 16 2020

아래 예제에서 메인 스레드는 자식 스레드로부터 알림을받지 않기 때문에 영원히 기다려야합니다. 그러나 주 스레드가 실행되고 아래 예제의 출력은 다음과 같습니다.

c
l
total: 19900

주 스레드가 실행되는 이유는 무엇입니까?

public class ThreadX extends Thread {
    static int total = 0;

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 200; i++) {
                total = total + i;
            }
            System.out.println("c");

        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadX t = new ThreadX();

        t.start();
        synchronized (t) {
            t.wait();
            System.out.println("l");
        }

        System.out.println("total: " + total);

    }
}

답변

10 akuzminykh Aug 16 2020 at 09:58

질문 본문에 대한 답변

확인 Thread#join(long):

[...] 스레드가 종료되면 this.notifyAll메서드가 호출됩니다. [...]

영원히를 의미하는으로 Thread#join()해당 함수 를 호출합니다 0.

[...] 시간 초과가 0이면 영원히 기다린다는 의미입니다.

따라서 귀하의 경우 여기에서 종료 될 때 t호출 notifyAll하면 대기중인 메인 스레드에 알립니다 t.


이 직관적이지 않은 동작은 문서에 다음을 작성하는 이유입니다.

이 응용 프로그램을 사용하지 않는 것이 좋습니다 wait, notify또는 notifyAllThread인스턴스.

질문 제목에 대한 답변

체크 아웃 Object#wait(또는 JLS (17.2.1. Wait) ) :

스레드는 알림, 중단 또는 시간 초과없이 깨어날 수있는 이른바 스퓨리어스 깨우기라고합니다. 실제로는 거의 발생하지 않지만 애플리케이션은 스레드가 깨어나야하는 조건을 테스트하고 조건이 충족되지 않으면 계속 대기하여이를 방지해야합니다.

따라서 Java의 스레드는 언제든지 깨어날 수 있습니다. 가짜 깨우기는 그다지 가능성이 없지만 발생할 수 있습니다.