¿Cuál es la diferencia entre a wait()
y sleep()
en Threads?
¿Entiendo que un wait()
subproceso -ing todavía está en modo de ejecución y usa ciclos de CPU pero un sleep()
-ing no consume ningún ciclo de CPU correcto?
¿Por qué tenemos ambos wait()
y sleep()
: cómo varía su implementación en un nivel inferior?
Respuestas:
A
wait
puede ser "despertado" por otro hilo que llamanotify
al monitor que se está esperando mientras que asleep
no se puede. También unwait
(ynotify
) debe suceder en un bloquesynchronized
en el objeto del monitor, mientrassleep
que no:En este punto, el hilo actualmente en ejecución espera y libera el monitor . Otro hilo puede hacer
(en el mismo
mon
objeto) y el primer subproceso (suponiendo que sea el único subproceso que espera 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, solo uno de los hilos podrá agarrar el monitor (recuerde quewait
está en unsynchronized
bloque) y continuar; los demás se bloquearán hasta que puedan adquirir el bloqueo del monitor.Otro punto es que usted llama
wait
enObject
sí mismo (es decir, espera en el monitor de un objeto), mientras que se llamasleep
elThread
.Sin embargo, otro punto es que se puede obtener activaciones falsas de
wait
(es decir, el hilo que está esperando hojas de vida sin razón aparente). Usted debe siemprewait
mientras que hace girar en alguna condición de la siguiente manera:fuente
wait
/notify
se usan generalmente para esperar a que algún otro subproceso realice una tarea o para esperar hasta que se cumpla una determinada condición.Una diferencia clave que aún no se menciona es que mientras duerme un Thread no libera los bloqueos que contiene, mientras que espera libera el bloqueo del objeto que
wait()
se activa.fuente
sleep
tiene bloqueos de Java , pero no lo hace. Para tener una comparación justa, compararíamossynchronized(OUTER_LOCK){ Thread.sleep(1000); }
consynchronized(OUTER_LOCK){ synchronized(LOCK){LOCK.wait();} }
y podemos ver que ambas instrucciones no liberan elOUTER_LOCK
. Si hay alguna diferencia, podemos decir quesleep
no utiliza explícitamente los bloqueos de Java , pero la pregunta es acerca de la cita "¿cómo varía su implementación en un nivel inferior?" entre comillaswait()
está asociado con la condición del bloqueo más interno desde el que se llama, en su ejemplo de código,wait()
solo se puede liberarLOCK
y noOUTER_LOCK
. Así es como el monitor Java está diseñado de todos modos. Una comparación justa seríasynchronized(OUTER_LOCK){ synchronized(LOCK) { Thread.sleep(1000); } }
ysynchronized(OUTER_LOCK){ synchronized(LOCK) { LOCK.wait(); } }
. En este casosleep()
mantendrá ambas cerraduras mientraswait()
se liberaráLOCK
pero aún se mantendráOUTER_LOCK
Encontré esta publicación útil. Se pone la diferencia entre
Thread.sleep()
,Thread.yield()
yObject.wait()
en términos humanos. Citar:fuente
sleep(n)
está implícitamente diciendo que el hilo actualmente en ejecución renuncia voluntariamente al monitor de la cerradura, lo cual no es cierto . Cita del javadoc de Thread : "El hilo no pierde la propiedad de ningún monitor".sleep
que no tiene ningún comportamiento especial con respecto al monitor que cualquier otra llamada al método Java, es decir, no interactúa ni los modifica de ninguna manera. Si quisiera decir algo sobre los monitores, debe especificar quewait
, además de lo dicho anteriormente, renuncie temporalmente al bloqueo del objeto al que se llama.wait(n)
para compararsleep(n)
. No tiene sentido comparar usando uno sin argumentos.Aquí hay muchas respuestas, 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 subproceso a dormir como estaba antes, solo empaqueta el contexto y deja de ejecutarse por un tiempo predefinido. Entonces, para despertarlo antes de tiempo, debe conocer la referencia de subproceso. Esta no es una situación común en un entorno multiproceso. Se utiliza principalmente para la sincronización de tiempo (por ejemplo, despertar en exactamente 3,5 segundos) y / o la imparcialidad codificada (solo duerme un rato y deja que otros hilos funcionen).wait()
, por el contrario, es un mecanismo de sincronización de hilo (o mensaje) que le permite notificar un hilo del cual no tiene referencia almacenada (ni cuidado). Puede pensarlo como un patrón de publicación-suscripción (wait
== suscribirse ynotify()
== publicar). Básicamente, utilizando la notificación () está enviando un mensaje (que incluso podría no recibirse y normalmente no le importa).En resumen, normalmente se usa
sleep()
para sincronización de tiempo ywait()
para sincronización de subprocesos múltiples.Se podrían implementar de la misma manera en el sistema operativo subyacente, o en absoluto (ya que las versiones anteriores de Java no tenían multiprocesamiento real; 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 de acuerdo con la VM / OS / HW en la que se ejecuta.
fuente
Aquí, he enumerado algunas diferencias importantes entre
wait()
y lossleep()
métodos.PD: También haga clic en los enlaces para ver el código de la biblioteca (funcionamiento interno, solo juegue un poco para comprenderlo mejor).
Espere()
wait()
El método libera el bloqueo.wait()
Es el método deObject
clase.wait()
es el método no estáticopublic final void wait() throws InterruptedException { //...}
wait()
debe ser notificado pornotify()
onotifyAll()
métodos.wait()
El método debe llamarse desde un bucle para tratar la falsa alarma.wait()
Se debe llamar al método desde el contexto sincronizado (es decir, el método o bloque sincronizado), de lo contrario arrojaráIllegalMonitorStateException
dormir()
sleep()
El método no libera el bloqueo.sleep()
Es el método dejava.lang.Thread
clase.sleep()
es el método estáticopublic static void sleep(long millis, int nanos) throws InterruptedException { //... }
sleep()
se completa.sleep()
mejor no llamar desde el bucle (es decir, ver el código a continuación ).sleep()
Se puede llamar desde cualquier lugar. No hay requisitos específicos.Ref: diferencia entre esperar y dormir
Fragmento de código para llamar al método de espera y suspensión
fuente
Thread.sleep()
se usa para hacer que el tiempo del procesador esté disponible para los otros hilos. el período de suspensión se puede terminar por interrupciones (es decir, por JVM). Lea este stackoverflow.com/questions/4264355/…notify()
onotifyAll()
sonObject
métodos de clase. por lo tanto están disponibles serán obj de toda clase (es decir, aquí también conThread
clase). vea el código grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…Hay algunas notas clave de diferencia que concluyo después de trabajar en esperar y dormir, primero eche un vistazo a la muestra usando wait () y sleep ():
Ejemplo1 : usando wait () y sleep ():
Deja en claro algunas notas clave:
Por favor corrígeme si estoy equivocado.
fuente
Diferencia entre wait () y sleep ()
La diferencia fundamental es que
wait()
es deObject
ysleep()
es un método estático deThread
.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 de lo contrario obtenemos unIllegalMonitorStateException
, mientras quesleep()
puede llamarse en cualquier lugar.wait()
, debe llamarnotify()
onotifyAll()
. En cuantosleep(),
al hilo se inicia después de un intervalo de tiempo especificado.Similitudes
fuente
Esta es una pregunta muy simple, porque ambos métodos tienen un uso totalmente diferente.
La principal diferencia es esperar para liberar el bloqueo o monitor mientras el modo de suspensión no libera ningún bloqueo o monitor mientras espera. La espera se utiliza para la comunicación entre subprocesos, mientras que la suspensión se usa para introducir la pausa en la ejecución.
Esta fue solo una explicación clara y básica, si desea más que eso, continúe leyendo.
En caso de
wait()
que el subproceso del método pase al estado de espera y no volverá automáticamente hasta que llamemos alnotify()
método (onotifyAll()
si tiene más de un subproceso en estado de espera y desea activar todos esos subprocesos). Y se necesita una sincronización o bloqueo de objeto o clase de bloqueo para acceder a lawait()
onotify()
onotifyAll()
métodos. Y una cosa más, elwait()
método se usa para la comunicación entre subprocesos porque si un subproceso pasa a estado de espera, necesitará otro subproceso para activar ese subproceso.Pero en este caso,
sleep()
es un método que se utiliza para mantener el proceso durante unos segundos o el tiempo que desea. Debido a que no es necesario para provocar algunanotify()
onotifyAll()
método para conseguir que de nuevo hilo. O no necesita ningún otro hilo para volver a llamar ese hilo. Como si quieres que algo suceda después de unos segundos, como en un juego después del turno del usuario, quieres que el usuario espere hasta que la computadora juegue, entonces puedes mencionar elsleep()
método.Y una diferencia más importante que se pregunta a menudo en las entrevistas:
sleep()
pertenece a laThread
clase ywait()
pertenece a laObject
clase.Estas son todas las diferencias entre
sleep()
ywait()
.Y hay una similitud entre ambos métodos: ambos son una declaración verificada, por lo que debe intentar atrapar o lanzar para acceder a estos métodos.
Espero que esto ayude.
fuente
fuente: http://www.jguru.com/faq/view.jsp?EID=47127
fuente
Esperar y dormir son dos cosas diferentes:
sleep()
el hilo deja de funcionar durante la duración especificada.wait()
el subproceso deja de funcionar hasta que el objeto que se está esperando es notificado, generalmente por otros subprocesos.fuente
sleep
, si desea que se detenga hasta que una entrada provenga del otro que usawait
/notify
.interrupt
pretende ser una forma de señalar a un hilo que debe dejar de hacer lo que está haciendo y terminar. Se manejasleep
,wait
pero también bloquea las funciones de E / S (y puede implementar funciones con el mismo comportamiento llamando al métodoThread.interrupted()
). En cuanto al rendimiento, las funciones generalmente están optimizadas para el objetivo para el que fueron diseñadas.sleep
es un método deThread
,wait
es un método deObject
, por lo quewait/notify
es una técnica de sincronización de datos compartidos en Java (usando monitor ), perosleep
es un método simple de subproceso para detenerse.fuente
sleep () es un método que se utiliza para retener el proceso durante unos segundos o el tiempo que desea, pero en caso de que el hilo de método wait () pase al estado de espera y no volverá automáticamente hasta que llamemos a notify () o notifique a todos ().
La principal diferencia es que wait () libera el bloqueo o monitor mientras sleep () no libera ningún bloqueo o monitor mientras espera. La espera se usa para la comunicación entre subprocesos, mientras que la suspensión se usa para introducir la pausa en la ejecución, generalmente.
Thread.sleep () envía el hilo actual al estado "No ejecutable" durante cierto tiempo. El hilo mantiene los monitores que ha adquirido, es decir, si el hilo está actualmente en un bloque o método sincronizado, ningún otro hilo puede ingresar a este bloque o método. Si otro hilo llama a t.interrupt () despertará el hilo dormido. Tenga en cuenta que dormir es un método estático, lo que significa que siempre afecta al hilo actual (el que está ejecutando el método de suspensión). Un error común es llamar a t.sleep () donde t es un hilo diferente; incluso entonces, es el hilo actual el que dormirá, no el hilo t.
object.wait () envía el hilo actual al estado "No ejecutable", como sleep (), pero con un giro. Wait se llama en un objeto, no en un hilo; llamamos a este objeto el "objeto de bloqueo". Antes de llamar a lock.wait (), el hilo actual debe sincronizarse en el objeto de bloqueo; wait () luego libera este bloqueo y agrega el hilo a la "lista de espera" asociada con el bloqueo. Más tarde, otro hilo puede sincronizarse en el mismo objeto de bloqueo y llamar a lock.notify (). Esto despierta el hilo de espera original. Básicamente, wait () / notify () es como sleep () / interrupt (), solo el hilo activo no necesita un puntero directo al hilo dormido, sino solo al objeto de bloqueo compartido.
Deje categorizar todos los puntos anteriores:
Call on:
Synchronized:
Hold lock:
Wake-up condition:
Usage:
Ref: diff
sleep
ywait
fuente
En palabras simples, esperar es esperar hasta que otro hilo lo invoque mientras que dormir es "no ejecutar la siguiente instrucción" durante un período de tiempo específico.
Además, el sueño es un método estático en la clase Thread y funciona en thread, mientras que wait () está en la clase Object y se llama a un objeto
Otro punto, cuando llama a wait en algún objeto, el hilo involucrado sincroniza el objeto y luego espera. :)
fuente
wait
y lossleep
métodos son muy diferentes:sleep
no tiene forma de "despertar",wait
tiene una forma de "despertar" durante el período de espera, por otro hilo llamandonotify
onotifyAll
.Ahora que lo pienso, los nombres son confusos a ese respecto; sin embargo,
sleep
es un nombre estándar ywait
es comoWaitForSingleObject
oWaitForMultipleObjects
en la API de Win.fuente
De esta publicación: http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-java/
Método wait ().
1) El hilo que llama al método wait () libera el bloqueo que contiene.
2) El subproceso recupera el bloqueo después de que otros subprocesos llaman a los métodos notify () o notifyAll () en el mismo bloqueo.
3) el método wait () debe llamarse dentro del bloque sincronizado.
4) el método wait () siempre se llama a los objetos.
5) Los hilos en espera pueden ser despertados por otros hilos llamando a los métodos notify () o notifyAll ().
6) Para llamar al método wait (), el hilo debe tener bloqueo de objeto.
método sleep ()
1) El hilo que llama al método sleep () no libera el bloqueo que contiene.
2) el método sleep () se puede llamar dentro o fuera del bloque sincronizado.
3) el método sleep () siempre se llama en subprocesos.
4) Los hilos dormidos no pueden ser despertados por otros hilos. Si lo hace, el hilo arrojará la InterruptedException.
5) Para llamar al método sleep (), el hilo no necesita tener bloqueo de objeto.
fuente
Aquí wait () estará en el estado de espera hasta que lo notifique otro subproceso, pero where as sleep () tendrá algún tiempo ... después de eso se transferirá automáticamente al estado Ready ...
fuente
wait()
Es un método deObject
clase.sleep()
Es un método deThread
clase.sleep()
permite que el hilo pase alsleep
estado por x milisegundos.Cuando un hilo entra en estado de suspensión
it doesn’t release the lock
.wait()
permite que el hilo libere el bloqueo ygoes to suspended state
.Este hilo estará activo cuando se llame a un método
notify()
onotifAll()
para el mismo objeto.fuente
Una gran diferencia potencial entre dormir / interrumpir y esperar / notificar es que
interrupt()
durantesleep()
siempre produce una excepción (por ejemplo, InterruptedException ), mientras quenotify()
durantewait()
no lo hace.Generar una excepción cuando no es necesario es ineficiente. Si tiene subprocesos que se comunican entre sí a una velocidad alta, generaría muchas excepciones si estuviera llamando a interrupción todo el tiempo, lo que es un desperdicio total de CPU.
fuente
Tienes razón: Sleep () hace que ese subproceso se "duerma" y la CPU se apagará y procesará otros subprocesos (también conocidos como cambio de contexto), aunque creo que Wait mantiene a la CPU procesando el subproceso actual.
Tenemos ambos porque, aunque puede parecer sensato permitir que otras personas usen la CPU mientras no la está utilizando, en realidad hay una sobrecarga en el cambio de contexto; dependiendo de cuánto tiempo duerma, puede ser más costoso en los ciclos de la CPU para cambiar los hilos de lo que es simplemente hacer que su hilo no haga nada durante unos pocos ms.
También tenga en cuenta que el sueño fuerza un cambio de contexto.
Además, en general no es posible controlar el cambio de contexto, durante la espera, el sistema operativo puede (y esperará por más tiempo) elegir procesar otros hilos.
fuente
interrupt
. El tiempo final están
adentrowait(n)
. ¶¶ ¡Han pasado 8 años y todavía nadie tiene la respuesta!Los métodos se usan para diferentes cosas.
Thread.sleep (n) puede interrumpirse, pero Object.wait () debe ser notificado. Es posible especificar el tiempo máximo de espera:
Object.wait(5000)
por lo que sería posible usarlowait
, er,sleep
pero luego tienes que molestarte con las cerraduras.Ninguno de los métodos utiliza la CPU mientras duerme / espera.
Los métodos se implementan usando código nativo, usando construcciones similares pero no de la misma manera.
Búsquelo usted mismo: ¿está disponible el código fuente de los métodos nativos? El archivo
/src/share/vm/prims/jvm.cpp
es el punto de partida ...fuente
Thread.sleep(big_num)
debe ser interrumpidoObject.wait(small_num)
puede ser notificadoWait () y sleep () ¿Diferencias?
Thread.sleep () Una vez que se completa su trabajo, solo se libera el bloqueo para todos. hasta que nunca suelte la cerradura a nadie.
Object.wait () Cuando vaya a la etapa de espera, se soltará la tecla y esperará algunos segundos según el parámetro.
Por ejemplo:
si tomas el café con la mano derecha, puedes tomar otra persona de la misma mano, cuando la dejes, solo tomarás otro objeto del mismo tipo aquí. además. esto es dormir () tu hora de dormir no trabajaste, solo estás durmiendo ... lo mismo aquí también.
Espere(). cuando te desaniman y tomas otro significado mientras esperas, eso es esperar
estás jugando películas o cualquier cosa en tu sistema igual que el reproductor, no puedes jugar más de una a la vez, es aquí, cuando cierras y eliges otra película o canción de cualquier persona, mientras se llama esperar
fuente
wait
libera el bloqueo ysleep
no lo hace. Un hilo en el estado de espera es elegible para despertarse tan pronto como seanotify
onotifyAll
que se llama. Pero en caso de quesleep
el hilo mantenga el bloqueo y solo será elegible una vez que termine el tiempo de suspensión.fuente
InterruptedException
lanza @Geek An , tal como se dice en el Javadoc.sleep()
El método hace que el subproceso actual pase del estado de ejecución al estado de bloqueo durante un tiempo especificado. Si el hilo actual tiene el bloqueo de cualquier objeto, entonces lo mantiene, lo que significa que otros hilos no pueden ejecutar ningún método sincronizado en ese objeto de clase.wait()
El método hace que el subproceso actual entre en estado de bloque durante un tiempo específico o hasta que se notifique, pero en este caso el subproceso libera el bloqueo del objeto (lo que significa que otros subprocesos pueden ejecutar cualquier método sincronizado del objeto que llama.fuente
En mi opinión, la principal diferencia entre ambos mecanismos es que dormir / interrumpir es la forma más básica de manejar hilos, mientras que esperar / notificar es una abstracción destinada a facilitar la comunicación entre hilos. Esto significa que dormir / interrumpir puede hacer cualquier cosa, pero que esta tarea específica es más difícil de hacer.
¿Por qué esperar / notificar es más adecuado? Aquí hay algunas consideraciones personales:
Hace cumplir la centralización. Permite coordinar la comunicación entre un grupo de hilos con un solo objeto compartido. Esto simplifica mucho el trabajo.
Aplica la sincronización. Porque hace que el programador envuelva la llamada para esperar / notificar en un bloque sincronizado.
Es independiente del origen y el número del hilo. Con este enfoque, puede agregar más subprocesos arbitrariamente sin editar los otros subprocesos o realizar un seguimiento de los existentes. Si usó dormir / interrumpir, primero necesitaría mantener las referencias a los hilos dormidos, y luego interrumpirlos uno por uno, a mano.
Un ejemplo de la vida real que es bueno para explicar esto es un restaurante clásico y el método que utiliza el personal para comunicarse entre ellos: los camareros dejan las solicitudes del cliente en un lugar central (un tablero de corcho, una mesa, etc.), suena una campana, y los trabajadores de la cocina vienen a tomar tales pedidos. Una vez que hay algún curso listo, el personal de la cocina vuelve a tocar el timbre para que los camareros estén al tanto y se los lleven a los clientes.
fuente
El ejemplo sobre el sueño no libera el bloqueo y la espera sí
Aquí hay dos clases:
Singleton : esta es una clase singleton con dos métodos estáticos getInstance () y getInstance (boolean isWait).
y
Ahora ejecute este ejemplo, obtendrá el siguiente resultado:
Aquí las instancias Singleton creadas por threadA y threadB son las mismas. Significa que threadB está esperando afuera hasta que threadA libere su bloqueo.
Ahora cambie Singleton.java comentando Thread.sleep (500); método y descomentar Singleton.class.wait (500); . Aquí por Singleton.class.wait (500); El método threadA liberará todos los bloqueos de adquisición y pasará al estado "No ejecutable", el threadB obtendrá el cambio para ingresar en el bloque sincronizado.
Ahora corre de nuevo:
Aquí las instancias Singleton creadas por threadA y threadB NO son las mismas debido a que threadB consiguió un cambio para ingresar en el bloque sincronizado y después de 500 milisegundos, threadA comenzó desde su última posición y creó un objeto Singleton más.
fuente
Debe llamarse desde el bloque sincronizado: el
wait()
método siempre se llama desde el bloque sincronizado, es decir, elwait()
método debe bloquear el monitor de objetos antes del objeto en el que se llama. Pero elsleep()
método se puede llamar desde un bloque sincronizado externo, es decir, elsleep()
método no necesita ningún monitor de objetos.IllegalMonitorStateException: si
wait()
se llama al método sin adquirir el bloqueo del objeto queIllegalMonitorStateException
se lanza en tiempo de ejecución, pero elsleep()
método nunca arroja dicha excepción.Pertenece a qué clase: el
wait()
método pertenece a lajava.lang.Object
clase pero elsleep()
método pertenece a lajava.lang.Thread
clase.Llamado en objeto o hilo: el
wait()
método se llama en objetos pero elsleep()
método se llama en hilos, no en objetos.Estado Tema: cuando
wait()
se llama al método de objeto, subproceso de supervisión de dicho objeto Holded pasa de correr a estado de espera y puede volver al estado ejecutable sólo cuandonotify()
onotifyAll()
método que se llama en ese objeto. Y luego, el planificador de subprocesos programa ese subproceso para pasar del estado ejecutable al estado en ejecución. cuandosleep()
se llama en el subproceso, pasa del estado de ejecución al estado de espera y puede volver al estado de ejecución cuando el tiempo de inactividad se ha agotado.Cuando se llama desde un bloque sincronizado: cuando
wait()
se llama al método, el hilo deja el bloqueo del objeto. Pero elsleep()
método cuando se llama desde el bloque sincronizado o el hilo del método no deja el bloqueo del objeto.Para más referencia
fuente
Desde la página de documentación de Oracle en el método wait () de
Object
:notify()
método o elnotifyAll()
método para este objeto. En otras palabras, este método se comporta exactamente como si simplemente realizara la llamadawait(0)
.Este método arroja
IllegalMonitorStateException
- si el hilo actual no es el propietario del monitor del objeto.InterruptedException
- si algún hilo interrumpió el hilo actual antes o mientras el hilo actual estaba esperando una notificación. El estado interrumpido del hilo actual se borra cuando se lanza esta excepción.Desde la página de documentación de Oracle sobre el método de clase sleep ()
Thread
:Este método arroja:
IllegalArgumentException
- si el valor de millis es negativoInterruptedException
- si algún hilo ha interrumpido el hilo actual. El estado interrumpido del hilo actual se borra cuando se lanza esta excepción.Otra diferencia clave:
wait()
es un método no estático (método de instancia) a diferencia del método estáticosleep()
(método de clase).fuente
wait()
se proporciona dentro de un método sincronizado, mientras quesleep()
se proporciona dentro de un método no sincronizado porque elwait()
método libera el bloqueo del objeto perosleep()
oyield()
libera ellock()
.fuente
sleep()
puede estar dentro de unsynchronized
bloque o método. La respuesta no explica nada.wait(1000)
hace que el hilo actual duerma hasta un segundo .notify()
onotifyAll()
llamada al método.sleep(1000)
hace que el subproceso actual se suspenda durante exactamente 1 segundo .fuente
sleep(1000)
no garantiza dormir por exactamente 1 segundo. Puede ser interrumpido antes.En realidad, todo esto se describe claramente en los documentos de Java (pero me di cuenta de esto solo después de leer las respuestas).
http://docs.oracle.com/javase/8/docs/api/index.html :
wait (): el subproceso actual debe ser el propietario del monitor de este objeto. El subproceso libera la propiedad de este monitor y espera hasta que otro subproceso notifique a los subprocesos que esperan en el monitor de este objeto para que se activen mediante una llamada al método de notificación o al método de notificación completa. El subproceso luego espera hasta que pueda volver a obtener la propiedad del monitor y reanude la ejecución.
sleep (): hace que el subproceso que se está ejecutando actualmente se suspenda (cesa temporalmente la ejecución) durante el número especificado de milisegundos, sujeto a la precisión y exactitud de los temporizadores y programadores del sistema. El hilo no pierde la propiedad de ningún monitor.
fuente