Cuando llamar a wait() depende de alguna condición, las llamadas a wait() deben hacerse dentro de un bucle while
while
(condicion()) {
wait();
}
Esto es así para que el thread se detenga siempre que se de la condición, tanto si es la primera vez, como si hemos salido del wait() por alguna razón.
Una alternativa sugerente, pero errónea, sería
if
(condicion()){
wait();
}
Que sólo chequea la condición la primera vez. Esto está mal.
— Normalmente se sale del wait() porque otro thread hace un notify() o un notifyAll(). No podemos evitar el while salvo que sea posible demostrar que el notify() se ejecuta tras verificar que la condición es cierta y que si varios threads despiertan, es cierto para todos ellos. En general, puede ser difícil de demostrar.
— Incluso si podemos llegar a demostrar que un notify() garantiza que la condición se cumple, java no garantiza que el thread que despierta se ejecute inmediatamente: simplemente lo marca como “puede ejecutar”. Para cuando el thread ejecuta, la condición puede seguir siendo cierta, o puede que ya no lo sea. Eso puede ser difícil de garantizar.
—
Java no garantiza que un thread sólo pueda salir de una espera
con un notify(). Un thread puede
despertarse de forma espuria. En estos casos, o volvemos a verificar la
condición o el thread se pondría en
movimiento incorrectamente.
Esto depende más del sistema operativo que hay por debajo de java que de java
propiamente dicho.
Temas relacionados