Solo un hilo puede mantener el bloqueo de un objeto. Se deben llamar los métodos wait()
y notify()
mientras el hilo mantiene el bloqueo en el objeto al que llama estos métodos; si no lo hacen (por ejemplo, porque no se sincronizó en el objeto), obtendrá un IllegalMonitorStateException
.
Cuando llama al wait()
, el hilo abandona el bloqueo y entra en una lista de espera (deja de ejecutarse). Cuando wait()
regrese, el hilo habrá obtenido nuevamente el bloqueo. Sin embargo, el hilo que llama a notify()
sigue manteniendo el bloqueo, por lo que el hilo de espera no se reanudará antes de que el hilo de notificación salga del bloque o método synchronized
para que libere el bloqueo del objeto.
Al llamar al notify()
, el hilo no está liberando el bloqueo del objeto.
Una posible secuencia de eventos sería:
- Thread 1 entra en un bloque de
synchronized
, la obtención de la cerradura para el objeto
- Thread 1 llamadas
wait()
en el objeto, renunciar a la cerradura, detiene la ejecución
- Tema 2 entra en un bloque
synchronized
, la obtención de la cerradura para el objeto
- Tema 2 llamadas
notify()
en el objeto, pero todavía mantiene el bloqueo
- Tema 1 se despierta y trata de obtener el bloqueo, pero no puede porque Tema 2 todavía lo tiene (por lo del hilo 1 tiene que esperar a que el bloqueo)
- Tema 2 salidas del bloque
synchronized
y libera el bloqueo
- El subproceso 1 ahora puede obtener el candado y lo devuelve desde
wait()