Después de ejecutar wait (), ¿cuánto tiempo espera un hilo si no recibe una notificación de otros hilos?

Aug 16 2020

En el siguiente ejemplo, como el hilo principal no recibe notificaciones del hilo secundario, debería esperar eternamente. Pero el hilo principal se está ejecutando y el resultado del siguiente ejemplo es:

c
l
total: 19900

¿Por qué se ejecuta el subproceso principal?

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);

    }
}

Respuestas

10 akuzminykh Aug 16 2020 at 09:58

Respuesta al cuerpo de preguntas

Mira Thread#join(long):

[...] Cuando un hilo termina this.notifyAll, se invoca el método. [...]

Observe que Thread#join()llama a esa función con 0, lo que significa para siempre.

[...] Un tiempo de espera de 0 significa esperar eternamente.

Entonces, en su caso, aquí tsolo llama notifyAllcuando termina, lo que notifica al hilo principal que está esperando t.


Este comportamiento poco intuitivo es la razón por la que escriben lo siguiente en la documentación:

Se recomienda que las aplicaciones no utilizan wait, notifyo notifyAllen Threadcasos.

Respuesta al título de la pregunta

Verifique Object#wait(o JLS (17.2.1. Espere) ):

Un hilo puede despertarse sin que se le notifique, se interrumpa o se agote el tiempo, lo que se denomina un despertar espurio. Si bien esto rara vez ocurrirá en la práctica, las aplicaciones deben protegerse contra esto probando la condición que debería haber provocado la activación del hilo y continuar esperando si la condición no se cumple.

Por lo tanto, los subprocesos en Java pueden activarse en cualquier momento. No es muy probable que se produzca un despertar falso, pero puede suceder.