¿Qué sucede cuando llama al método notifyAll en un objeto que no está esperando? ¿Debe haber una excepción o es una situación normal?Java - espere y notifiqueTodo
Respuesta
Es completamente normal. Solo puede notificar a todos los que esperan en un solo monitor. Todos los demás no están interesados. El objeto al que llama notifyAll es solo el monitor en el que están esperando otros. Si nadie está esperando nadie debe ser notificado
Como puede ver aquí, la llamada a notifyAll() en un objeto que no está en espera no tiene ningún efecto.
Sólo espera recibir una notificación objetos. Object.wait() bloquea hasta que se agote el tiempo de espera o notifique, por lo que la pregunta sigue siendo ¿cómo o por qué piensas que los objetos que no están en espera recibirán alguna notificación? no tiene sentido.
Los objetos no esperan o son notificados, los hilos sí. Y es perfectamente posible y normal llamar a notifyAll() en un objeto de monitor sin saber si hay hilos esperando en él. Por ejemplo, en un escenario de productor/consumidor con una cola, el consumidor podría haber vaciado la cola y aún estar ocupado con el procesamiento cuando el productor agrega un nuevo elemento a la cola y notifica a todos los consumidores que están esperando (es decir, ninguno) sobre esto. –
Eliminé el hilo para mantener las cosas lo más simples posible. –
El objeto está "en espera", sin esperar. El hilo es el que está esperando. Si nadie está esperando, nadie se despertará y nada especial sucederá.
¿Qué sucede cuando se activa una alarma pero no hay nadie para escucharla? –
Situación perfectamente normal.
Digamos que tiene una cola con una cadena de producción que pone elementos en ella y una cadena de consumidores quitando elementos de ella.
Ahora el consumidor podría haber vaciado la cola y aún estar ocupado con el procesamiento, por lo que nadie está esperando a que la cola quede vacía. Ahora el productor agrega un nuevo elemento a la cola. Él tiene que llamar a notifyAll() para despertar al consumidor si estuviera esperando. Agregar lógica adicional para verificar si alguien está esperando y solo llamar a notifyAll() en ese caso agregaría una complejidad considerable (y propensa a fallas) al escenario - es mucho más fácil simplemente llamar a notifyAll() todo el tiempo.
Es posible que solo esté cortando pelos ;-) Puede que no sea estrictamente correcto pensar que los hilos pasen del estado "en espera" al estado "en ejecución" en notifyAll; al menos no sin la advertencia de que lo primero que hace un hilo notificado es volver a grabar el bloqueo del monitor. Y dado que solo uno de los hilos notificados puede capturarlo, los otros serán bloqueados. BLOCKED (Thread.State.Blocked) es el estado del subproceso. Pero el bloqueo es , no es lo mismo que esperar porque el hilo bloqueado no necesita otra señal de notify() para reanudar. [Bueno, sé de los despertadores espurios, pero tal vez lo contrario también podría ser cierto para algunas implementaciones de JVM: ¿una notificación perdida?]
public class HellBoy {
public static class MyThread extends Thread {
static final public Object sharedLock = new Object();
public void run() {
synchronized (sharedLock) {
System.out.println("Gonna wait...");
try {
sharedLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Woken up but sleeping with the lock");
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("exiting and unlocking");
}
}
}
public static void main(String[] args) throws Exception {
new MyThread().start();
new MyThread().start();
new MyThread().start();
new MyThread().start();
Thread.sleep(200);
synchronized (MyThread.sharedLock) {
MyThread.sharedLock.notifyAll();
}
}
}
¿Se puede perder una notificación? –
- 1. DTE.ExecuteCommand y espere
- 2. WebDriver - espere por el elemento usando Java
- 3. Java, no espere a que finalice un subproceso
- 4. ejecutores de Java: espere la finalización de la tarea.
- 5. EC2 Java Api Espere hasta que se cree Ec2 Instance.
- 6. Java Class - No espere a que el proceso para salir
- 7. Java: espere el proceso de ejecución hasta que salga
- 8. Selenium - Espere tráfico de red
- 9. Espere a que SwingWorker termine
- 10. Android - Cargando, espere
- 11. espere cada jQuery
- 12. Espere hasta que QWidget cierre
- 13. Espere a que [NSAlert beginSheetModalForWindow: ...];
- 14. Ejecute un programa de Emacs y no espere la salida
- 15. Ejecute una aplicación con PowerShell y espere hasta que finalice
- 16. Inicio del proceso asincrónico y espere a que finalice
- 17. Cree varios subprocesos y espere todos para completar
- 18. Espere a que TinyMCE cargue
- 19. Espere a que QueueUserWorkItem complete
- 20. C# espere un tiempo sin bloquear
- 21. Delegado - Excepciones No espere hasta llamar EndInvoke()
- 22. Espere a que tomcat termine de iniciar
- 23. Espere hasta que se cargue la función
- 24. QML: espere hasta que finalicen las animaciones
- 25. Espere la página en ASP.NET MVC
- 26. espere 3 segundos o haga clic en
- 27. Excel VBA mensaje emergente "Espere por favor"
- 28. ¿Cómo hago para que un subproceso espere a que JFrame se cierre en Java?
- 29. Espere hasta que se haya completado .append()
- 30. No espere operaciones longrunning ASP.NET MVC
No podría ser estrictamente correcto para poner un hilo de esperar a que se ejecuta en notifyAll o por lo menos no sin la advertencia de que la primera cosa que un hilo notificado hace es regrab el bloqueo del monitor. Y dado que solo uno de los hilos notificados puede atraparlo, los otros serán bloqueados. Pero bloquear no es lo mismo que esperar porque el hilo bloqueado no necesita otra señal de notify(). –