Diferencia entre "esperar()" y "dormir()" en Java
¿ Cuál es la diferencia entre a wait()
y sleep()
in Threads?
¿Tengo entendido que un wait()
subproceso -ing todavía está en modo de ejecución y utiliza ciclos de CPU pero un sleep()
-ing no consume ningún ciclo de CPU?
¿Por qué tenemos ambos wait()
y sleep()
?
¿Cómo varía su implementación a un nivel inferior?
A wait
puede ser "despertado" por otro hilo que llama notify
al monitor que está siendo esperado, mientras que a sleep
no puede. Además, wait
(y notify
) debe ocurrir en un bloque synchronized
en el objeto monitor, mientras que sleep
no:
Object mon = ...;
synchronized (mon) {
mon.wait();
}
En este punto, el hilo que se está ejecutando actualmente espera y libera el monitor . Otro hilo puede servir
synchronized (mon) { mon.notify(); }
(en el mismo mon
objeto) y el primer hilo (suponiendo que sea el único hilo esperando en el monitor) se activará.
También puede llamar notifyAll
si hay más de un hilo esperando en el monitor; esto los despertará a todos . Sin embargo, sólo uno de los hilos podrá tomar el monitor (recuerde que está wait
en un synchronized
bloque) y continuar; los demás quedarán bloqueados hasta que puedan adquirir el bloqueo del monitor.
Otro punto es que llamas wait
a Object
sí mismo (es decir, esperas en el monitor de un objeto) mientras llamas sleep
a Thread
.
Otro punto más es que puede obtener reactivaciones espuriaswait
(es decir, el hilo que está esperando se reanuda sin razón aparente). Siemprewait
debes mientras giras en alguna condición de la siguiente manera:
synchronized {
while (!condition) { mon.wait(); }
}
Una diferencia clave que aún no se menciona es que:
sleep()
no libera el bloqueo que mantiene en el Hilo,synchronized(LOCK) { Thread.sleep(1000); // LOCK is held }
wait()
libera el bloqueo que mantiene sobre el objeto.synchronized(LOCK) { LOCK.wait(); // LOCK is not held }
Esta publicación me resultó útil. Pone la diferencia entre Thread.sleep()
, Thread.yield()
y Object.wait()
en términos humanos. Citar:
Eventualmente, todo llega al programador del sistema operativo, que distribuye intervalos de tiempo a los procesos y subprocesos.
sleep(n)
dice "Terminé con mi segmento de tiempo y, por favor, no me des otro durante al menos n milisegundos". El sistema operativo ni siquiera intenta programar el hilo inactivo hasta que haya pasado el tiempo solicitado.
yield()
dice "Ya terminé con mi segmento de tiempo, pero todavía tengo trabajo por hacer". El sistema operativo es libre de darle inmediatamente al subproceso otro segmento de tiempo, o de darle a algún otro subproceso o procesar la CPU que el subproceso productivo acaba de abandonar.
wait()
dice “Ya terminé con mi segmento de tiempo. No me des otro intervalo de tiempo hasta que alguien llame a notificar()”. Al igual que consleep()
, el sistema operativo ni siquiera intentará programar su tarea a menos que alguien llamenotify()
(o se produzca uno de otros escenarios de activación).Los subprocesos también pierden el resto de su intervalo de tiempo cuando realizan IO de bloqueo y en algunas otras circunstancias. Si un subproceso funciona durante todo el intervalo de tiempo, el sistema operativo toma el control por la fuerza aproximadamente como si lo
yield()
hubieran llamado, para que otros procesos puedan ejecutarse.Rara vez lo necesita
yield()
, pero si tiene una aplicación de gran capacidad informática con límites lógicos de tareas, insertar unyield()
podría mejorar la capacidad de respuesta del sistema (a expensas de tiempo: los cambios de contexto, incluso solo entre el sistema operativo y viceversa, no son gratuitos). Mida y pruebe con los objetivos que le interesan, como siempre.
Hay muchas respuestas aquí, pero no pude encontrar la distinción semántica mencionada en ninguna.
No se trata del hilo en sí; Ambos métodos son necesarios ya que admiten casos de uso muy diferentes.
sleep()
envía el hilo a dormir como estaba antes, simplemente empaqueta el contexto y deja de ejecutarse durante un tiempo predefinido. Entonces, para activarlo antes de la hora prevista, necesita conocer la referencia del hilo. Esta no es una situación común en un entorno de subprocesos múltiples. Se utiliza principalmente para sincronización de tiempo (por ejemplo, despertarse en exactamente 3,5 segundos) y/o equidad codificada (simplemente dormir un rato y dejar que otros hilos funcionen).
wait()
, por el contrario, es un mecanismo de sincronización de hilos (o mensajes) que te permite notificar un Hilo del cual no tienes referencia almacenada (ni te importa). Puedes considerarlo como un patrón de publicación-suscripción ( wait
== suscribir y notify()
== publicar). Básicamente, al usar notify() estás enviando un mensaje (que podría incluso no recibirse y normalmente no te importa).
En resumen, normalmente se utiliza sleep()
para sincronización de tiempo y wait()
para sincronización de subprocesos múltiples.
Podrían implementarse de la misma manera en el sistema operativo subyacente, o no implementarse en absoluto (ya que las versiones anteriores de Java no tenían subprocesos múltiples reales; probablemente algunas máquinas virtuales pequeñas tampoco lo hacen). No olvide que Java se ejecuta en una VM, por lo que su código se transformará en algo diferente según la VM/OS/HW en la que se ejecuta.
Diferencia entre esperar() y dormir()
- La diferencia fundamental es que
wait()
es un método no estáticoObject
ysleep()
es un método estáticoThread
. - La principal diferencia es que
wait()
libera el bloqueo mientrassleep()
no libera ningún bloqueo mientras espera. wait()
se usa para la comunicación entre subprocesos, mientras quesleep()
se usa para introducir una pausa en la ejecución, generalmente.wait()
debe llamarse desde dentro de sincronizar o obtendremos unIllegalMonitorStateException
, mientras quesleep()
se puede llamar desde cualquier lugar.- Para iniciar un hilo nuevamente desde
wait()
, debes llamarnotify()
onotifyAll()
indefinidamente. En cuanto alsleep(),
hilo, se inicia definitivamente después de un intervalo de tiempo específico.
Similitudes
- Ambos hacen que el hilo actual entre en el estado No ejecutable .
- Ambos son métodos nativos .