1. Información general
En este breve artículo, echaremos un vistazo a los métodos estándar sleep () y wait () en el núcleo de Java, y comprenderemos las diferencias y similitudes entre ellos.
2. Diferencias generales entre esperar y dormir
En pocas palabras, wait () es un método de instancia que se utiliza para la sincronización de subprocesos.
Se puede llamar a cualquier objeto, como se define directamente en java.lang.Object, pero solo se puede llamar desde un bloque sincronizado . Libera el bloqueo del objeto para que otro hilo pueda entrar y adquirir un bloqueo.
Por otro lado, Thread.sleep () es un método estático que se puede llamar desde cualquier contexto. Thread.sleep () pausa el hilo actual y no libera ningún bloqueo.
Aquí hay un vistazo inicial muy simplista a estas dos API principales en acción:
private static Object LOCK = new Object(); private static void sleepWaitExamples() throws InterruptedException { Thread.sleep(1000); System.out.println( "Thread '" + Thread.currentThread().getName() + "' is woken after sleeping for 1 second"); synchronized (LOCK) { LOCK.wait(1000); System.out.println("Object '" + LOCK + "' is woken after" + " waiting for 1 second"); } }
La ejecución de este ejemplo producirá el siguiente resultado:
El hilo 'principal' se despierta después de dormir durante 1 segundo
El objeto '[email protected]' se despierta después de esperar 1 segundo
3. Despertar Espere y duerma
Cuando usamos el método sleep () , un hilo se inicia después de un intervalo de tiempo específico, a menos que se interrumpa.
Para wait () , el proceso de activación es un poco más complicado. Podemos despertar el hilo llamando a los métodos notificar () o notificar a todos () en el monitor que se está esperando.
Uso notifyAll () en lugar de notificar () cuando se quiere despertar a todos los temas que están en el estado de espera. De manera similar al método wait () en sí mismo, notificar () y notificar a todos () deben llamarse desde el contexto sincronizado.
Por ejemplo, así es como puede esperar :
synchronized (b) { while (b.sum == 0) { System.out.println("Waiting for ThreadB to complete..."); b.wait(); } System.out.println("ThreadB has completed. " + "Sum from that thread is: " + b.sum); }
Y luego, así es como otro hilo puede activar el hilo en espera, llamando a notify () en el monitor :
int sum; @Override public void run() { synchronized (this) { int i = 0; while (i < 100000) { sum += i; i++; } notify(); } }
La ejecución de este ejemplo producirá el siguiente resultado:
Esperando a que ThreadB se complete…
ThreadB se ha completado. La suma de ese hilo es: 704982704
4. Conclusión
Esta es una introducción rápida a la semántica de esperar y dormir en Java.
En general, deberíamos usar sleep () para controlar el tiempo de ejecución de un hilo y wait () para la sincronización multi-hilo. Naturalmente, hay mucho más por explorar, después de comprender bien los conceptos básicos.
Como siempre, puede consultar los ejemplos proporcionados en este artículo en GitHub.