Diferencia entre "esperar()" y "dormir()" en Java

Resuelto Geek asked hace 15 años • 33 respuestas

¿ 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?

Geek avatar Jun 24 '09 13:06 Geek
Aceptado

A waitpuede ser "despertado" por otro hilo que llama notifyal monitor que está siendo esperado, mientras que a sleepno puede. Además, wait(y notify) debe ocurrir en un bloque synchronizeden el objeto monitor, mientras que sleepno:

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 monobjeto) y el primer hilo (suponiendo que sea el único hilo esperando en el monitor) se activará.

También puede llamar notifyAllsi 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á waiten un synchronizedbloque) y continuar; los demás quedarán bloqueados hasta que puedan adquirir el bloqueo del monitor.

Otro punto es que llamas waita Objectsí mismo (es decir, esperas en el monitor de un objeto) mientras llamas sleepa 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(); }
}
oxbow_lakes avatar Jun 24 '2009 06:06 oxbow_lakes

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
     }
    
Robert Munteanu avatar Jun 24 '2009 07:06 Robert Munteanu

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 con sleep(), el sistema operativo ni siquiera intentará programar su tarea a menos que alguien llame notify()(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 un yield() 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.

E-rich avatar Aug 05 '2011 19:08 E-rich

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.

estani avatar Apr 19 '2012 10:04 estani

Diferencia entre esperar() y dormir()

  • La diferencia fundamental es que wait()es un método no estático Objecty sleep()es un método estático Thread.
  • La principal diferencia es que wait()libera el bloqueo mientras sleep()no libera ningún bloqueo mientras espera.
  • wait()se usa para la comunicación entre subprocesos, mientras que sleep()se usa para introducir una pausa en la ejecución, generalmente.
  • wait()debe llamarse desde dentro de sincronizar o obtendremos un IllegalMonitorStateException, mientras que sleep() se puede llamar desde cualquier lugar.
  • Para iniciar un hilo nuevamente desde wait(), debes llamar notify()o notifyAll()indefinidamente. En cuanto al sleep(),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 .
Premraj avatar Jul 24 '2015 06:07 Premraj