thread second crear java multithreading sleep java-threads

java - second - thread.sleep() c#



Diferencia entre esperar() y dormir() (30)

¿Cuál es la diferencia entre wait() y sleep() en subprocesos?

¿Tengo entendido que un subproceso de wait() está todavía en modo de ejecución y utiliza ciclos de CPU, pero una sleep() no consume ningún ciclo de CPU correcto?

¿Por qué tenemos tanto wait() como sleep() : cómo varía su implementación a un nivel inferior?


Diferencia entre esperar () y dormir ()

  • La diferencia fundamental es que wait() es de Object y sleep() es un método estático de Thread .

  • La principal diferencia es que wait() libera el bloqueo mientras que sleep() no libera ningún bloqueo mientras espera.

  • El wait() se utiliza para la comunicación entre subprocesos, mientras que sleep() se utiliza para introducir la pausa en la ejecución, en general.

  • El wait() debe llamar desde adentro para sincronizar o, de lo contrario, obtendremos IllegalMonitorStateException mientras que sleep() puede llamar a cualquier lugar.

  • Para volver a iniciar el subproceso desde wait() , debe llamar a notify() o a notifyAll() . Mientras está en sleep(), subproceso se inicia después del intervalo ms / seg especificado.

Similitudes que ayudan a entender.

  • Ambos hacen que el hilo actual pase al estado No ejecutable .
  • Ambos son métodos native .

dormir

  • Hace que el hilo en ejecución actual se duerma durante un tiempo específico.
  • Su precisión depende de los temporizadores y programadores del sistema.
  • Mantiene los monitores que ha adquirido, por lo que si se llama desde un contexto sincronizado, ningún otro hilo puede ingresar a ese bloque o método.
  • Si llamamos al método interrupt (), despertará el hilo de dormir.

Espere

  • Hace que el subproceso actual espere hasta que otro subproceso invoque el método notify () o el método notifyAll () para este objeto
  • Debe llamarse desde un contexto sincronizado, es decir, desde un bloque o método. Significa que antes de llamar al método wait (), el subproceso actual debe tener bloqueo en ese objeto.
  • Libera el bloqueo en el objeto en el que se llama y se agrega a la lista de espera, por lo que otro subproceso puede adquirir el bloqueo en el objeto.

  1. wait() es un método de la clase Object .
    sleep() es un método de la clase Thread .

  2. sleep() permite que el hilo pase al estado de sleep durante x milisegundos.
    Cuando un hilo entra en estado de suspensión it doesn''t release the lock .

  3. wait() permite que el hilo libere el bloqueo y goes to suspended state .
    Este subproceso estará activo cuando se notifAll() método notifAll() o notifAll() para el mismo objeto.


Aquí, he enumerado algunas diferencias importantes entre los métodos wait() y sleep() .
PD: También haga clic en los enlaces para ver el código de la biblioteca (trabajo interno, solo juegue un poco para una mejor comprensión).

wait()

  1. wait() método wait() libera el bloqueo.
  2. wait() es el método de la clase Object .
  3. wait() es el método no estático - public final void wait() throws InterruptedException { //...}
  4. wait() debe ser notificado por notify() métodos de notify() o notifyAll() .
  5. wait() método de wait() debe llamarse desde un bucle para tratar la falsa alarma.

  6. wait() método wait() debe llamarse desde un contexto sincronizado (es decir, un método o bloque sincronizado), de lo contrario lanzará la IllegalMonitorStateException

sleep()

  1. sleep() método sleep() no libera el bloqueo.
  2. sleep() es el método de la clase java.lang.Thread .
  3. sleep() es el método estático: public static void sleep(long millis, int nanos) throws InterruptedException { //... }
  4. después de la cantidad de tiempo especificada, se completa sleep() .
  5. sleep() mejor no llamar desde un bucle (es decir, ver el código a continuación ).
  6. sleep() puede ser llamado desde cualquier lugar. No hay ningún requisito específico.

Ref: Diferencia entre esperar y dormir.

Fragmento de código para el método de espera y suspensión de llamadas

synchronized(monitor){ while(condition == true){ monitor.wait() //releases monitor lock } Thread.sleep(100); //puts current thread on Sleep }


De este post: http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-java/

Espera () Método.

1) El hilo que llama al método wait () libera el bloqueo que mantiene.

2) El subproceso recupera el bloqueo después de que otros subprocesos llamen a los métodos notificar () o notificar a Todos () en el mismo bloqueo.

3) El método de espera () debe llamarse dentro del bloque sincronizado.

4) El método de espera () siempre se llama en objetos.

5) Los subprocesos en espera pueden ser activados por otros subprocesos llamando a los métodos de notificación () o notificarAll ().

6) Para llamar al método wait (), el hilo debe tener bloqueo de objeto.

dormir () Método

1) El hilo que llama al método sleep () no libera el bloqueo que mantiene.

2) El método sleep () se puede llamar dentro o fuera del bloque sincronizado.

3) El método sleep () siempre se llama en hilos.

4) Los hilos de dormir no pueden ser despertados por otros hilos. Si se hace así, el hilo lanzará InterruptedException.

5) Para llamar al método sleep (), el hilo no necesita tener bloqueo de objeto.


En palabras simples, esperar es esperar hasta que algún otro hilo lo invoque, mientras que el modo de espera es "no ejecutar la siguiente instrucción" durante un período específico de tiempo.

Además, sleep 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 en un objeto.

Otro punto, cuando llama a esperar en algún objeto, el hilo involucrado sincroniza el objeto y luego espera. :)


Esperar y dormir son dos cosas diferentes:

  • En sleep() el hilo deja de funcionar durante la duración especificada.
  • En wait() el subproceso deja de funcionar hasta que se notifica al objeto que está siendo esperado, generalmente por otros subprocesos.

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 el monitor mientras la suspensión no libera ningún bloqueo o monitor mientras se espera. La espera se utiliza para la comunicación entre subprocesos, mientras que la suspensión se utiliza para introducir una pausa en la ejecución.

Esta fue solo una explicación clara y básica, si quieres más que eso, continúa leyendo.

En caso de wait() subproceso del método wait() pase al estado de espera, no volverá a aparecer automáticamente hasta que llamemos al método notifyAll() (o notifyAll() si tiene más de un subproceso en estado de espera y desea reactivar todos esos hilos). Y necesita sincronizar o bloquear objetos o objetos para acceder a los métodos wait() o notify() o notify() notifyAll() . Y una cosa más, el método wait() se utiliza para la comunicación entre subprocesos porque si un subproceso entra en estado de espera, necesitará otro subproceso para activar ese subproceso.

Pero en el caso de sleep() este es un método que se utiliza para mantener el proceso durante unos segundos o el tiempo deseado. Porque no es necesario provocar ningún método de notify() o notifyAll() para recuperar ese hilo. O no necesita ningún otro hilo para recuperar ese hilo. Si desea que algo suceda después de unos segundos, como en un juego después del turno del usuario, desea que el usuario espere hasta que la computadora juegue, puede mencionar el método sleep() .

Y otra diferencia importante que se pregunta a menudo en las entrevistas: sleep() pertenece a la clase Thread y wait() pertenece a la clase Object .

Estas son todas las diferencias entre sleep() y wait() .

Y existe una similitud entre ambos métodos: ambos son una declaración marcada, por lo que debe intentar atraparlos o lanzarlos para acceder a estos métodos.

Espero que esto ayude.


Hay algunas diferencias en las notas clave que concluyo después de trabajar en esperar y dormir, primero eche un vistazo a la muestra con esperar () y dormir ():

Ejemplo 1 : usando wait () y sleep ():

synchronized(HandObject) { while(isHandFree() == false) { /* Hand is still busy on happy coding or something else, please wait */ HandObject.wait(); } } /* Get lock ^^, It is my turn, take a cup beer now */ while (beerIsAvailable() == false) { /* Beer is still coming, not available, Hand still hold glass to get beer, don''t release hand to perform other task */ Thread.sleep(5000); } /* Enjoy my beer now ^^ */ drinkBeers(); /* I have drink enough, now hand can continue with other task: continue coding */ setHandFreeState(true); synchronized(HandObject) { HandObject.notifyAll(); }

Dejemos en claro algunas notas clave:

  1. Llamar al
    • wait (): llamada en el hilo actual que contiene HandObject Object
    • sleep (): llamada en ejecución de subprocesos obtener cerveza (es un método de clase, por lo que afecta al hilo en ejecución actual)
  2. Sincronizado
    • wait (): cuando el acceso a varios subprocesos está sincronizado, el mismo objeto (HandObject) (cuando se necesita comunicación entre más de un subproceso (el subproceso ejecuta la codificación, el subproceso ejecuta obtener cerveza) en el mismo objeto HandObject)
    • dormir (): cuando la condición de espera para continuar la ejecución (cerveza en espera disponible)
  3. Mantener bloqueo :
    • wait (): libere el bloqueo para que otro objeto tenga oportunidad de ejecutarse (HandObject es gratis, puede hacer otro trabajo)
    • dormir (): mantener el bloqueo por lo menos t veces (o hasta que se interrumpa) (mi trabajo aún no ha finalizado, continuaré manteniendo el bloqueo y esperando alguna condición para continuar)
  4. Condición de despertar :
    • espere (): hasta que notifique (), notifique a All () del objeto
    • sleep (): hasta que al menos el tiempo expire o interrumpa la llamada
  5. Y el último punto es usar cuando estani indique:

normalmente usas sleep () para sincronización de tiempo y wait () para sincronización de subprocesos múltiples.

Por favor corrígeme si estoy equivocado.


Hay muchas respuestas aquí pero no pude encontrar la distinción semántica mencionada en ninguna.

No se trata del hilo en sí mismo; ambos métodos son necesarios ya que admiten casos de uso muy diferentes.

sleep() envía el subproceso para dormir como estaba antes, solo empaqueta el contexto y deja de ejecutarse por un tiempo predefinido. Por lo tanto, para activarlo antes de la hora debida, debe conocer la referencia de Thread. Esta no es una situación común en un entorno de subprocesos múltiples. Se usa principalmente para la sincronización de tiempo (por ejemplo, despertar en exactamente 3,5 segundos) y / o imparcialidad codificada (solo dormir durante un tiempo y dejar que otros subprocesos funcionen).

wait() , por el contrario, es un mecanismo de sincronización de subprocesos (o mensajes) que le permite notificar a un Subproceso del que no tiene referencia almacenada (ni atención). Puedes considerarlo como un patrón de publicación-suscripción ( wait == suscribirte y notify() == publicar). Básicamente, al utilizar notificar (), está enviando un mensaje (que puede que incluso no se reciba y que normalmente no le importa).

Para resumir, normalmente se usa sleep() para la sincronización de tiempo y wait() para la sincronización de subprocesos múltiples.

Se podrían implementar de la misma manera en el sistema operativo subyacente, o no se implementaron (ya que las versiones anteriores de Java no tenían multihilo 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.


He encontrado esta publicación útil. Pone la diferencia entre Thread.sleep() , Thread.yield() y Object.wait() en términos humanos. Citar:

Eventualmente, todo se reduce al programador del sistema operativo, que distribuye los intervalos de tiempo a los procesos y subprocesos.

sleep(n) dice "He terminado con mi intervalo de tiempo, y por favor no me des otro por al menos n milisegundos". El sistema operativo ni siquiera intenta programar el hilo de dormir hasta que haya transcurrido el tiempo solicitado.

yield() dice: "He terminado con mi intervalo de tiempo, pero todavía tengo trabajo por hacer". El sistema operativo es libre de darle de inmediato al hilo otro intervalo de tiempo, o de darle a otro hilo o procesar a la CPU el hilo de rendimiento que acaba de abandonar .

wait() dice: "He terminado con mi intervalo de tiempo. No me des otro intervalo de tiempo hasta que alguien llame a notificar (). ” Al igual que con el modo de sleep() , el sistema operativo ni siquiera intentará programar su tarea a menos que alguien llame a notify() (o se produzca uno de algunos otros escenarios de activación).

Los hilos también pierden el resto de su intervalo de tiempo cuando realizan el bloqueo de IO y en algunas otras circunstancias. Si un hilo funciona a lo largo de todo el intervalo de tiempo, el sistema operativo toma el control a la fuerza, aproximadamente, como si se hubiera llamado a yield() , para que otros procesos puedan ejecutarse.

Rara vez necesita el yield() , pero si tiene una aplicación de cómputo con límites de tareas lógicas, insertar un yield() podría mejorar la capacidad de respuesta del sistema (a expensas del tiempo, los cambios de contexto, incluso solo para el sistema operativo y viceversa, no son '''' t libre). Mide y prueba contra los objetivos que te interesan, como siempre.


Los métodos se utilizan para diferentes cosas.

Thread.sleep(5000); // Wait until the time has passed. Object.wait(); // Wait until some other thread tells me to wake up.

Se puede interrumpir Thread.sleep (n) , pero se debe notificar a Object.wait () . Es posible especificar el tiempo máximo de espera: Object.wait(5000)por lo tanto, se podría usar waitpara, er, sleeppero luego hay que molestarse con los bloqueos.

Ninguno de los métodos utiliza la CPU mientras duerme / espera.

Los métodos se implementan utilizando código nativo, usando construcciones similares pero no de la misma manera.

Busque usted mismo: ¿Está disponible el código fuente de los métodos nativos? El archivo /src/share/vm/prims/jvm.cppes el punto de partida ...


Una diferencia clave que aún no se ha mencionado es que, mientras duerme, un subproceso no libera los bloqueos que mantiene, mientras espera libera el bloqueo en el objeto al que se llama a wait() .

synchronized(LOCK) { Thread.sleep(1000); // LOCK is held } synchronized(LOCK) { LOCK.wait(); // LOCK is not held }


Una gran diferencia potencial entre el modo de espera / interrupción y la espera / notificación es que

Generar una excepción cuando no es necesaria es ineficiente. Si tiene subprocesos que se comunican entre sí a una velocidad alta, entonces se generarían muchas excepciones si estuviera llamando a la interrupción todo el tiempo, lo que es una pérdida total de CPU.


Una llamada puede ser "despertada" por otro subproceso que llama a notify en el monitor en el que se está esperando, mientras que una sleep no puede. También debe ocurrir una wait (y notify ) en un bloque synchronized en el objeto monitor, mientras que la sleep no:

Object mon = ...; synchronized (mon) { mon.wait(); }

En este punto, el hilo en ejecución actualmente espera y libera el monitor . Otro hilo puede hacer

synchronized (mon) { mon.notify(); }

(en el mismo objeto mon ) y el primer hilo (asumiendo que es el único hilo que espera en el monitor) se activará.

También puede llamar a notifyAll si hay más de un hilo en espera en el monitor; esto los despertará a todos . Sin embargo, solo una de las hebras podrá agarrar el monitor (recuerde que la wait está en un bloque synchronized ) y continuar: los demás se bloquearán hasta que puedan adquirir el bloqueo del monitor.

Otro punto es que se llama a la wait en el Object sí (es decir, se espera en el monitor de un objeto) mientras que se llama a la sleep en el Thread .

Otro punto más es que puede obtener activaciones falsas de la wait (es decir, el hilo que está esperando se reanuda sin ninguna razón aparente). Siempre debes wait mientras giras en alguna condición de la siguiente manera:

synchronized { while (!condition) { mon.wait(); } }


Usted tiene razón: el modo Sleep () hace que el hilo se "duerma" y la CPU se apagará y procesará otros hilos (también conocidos como cambio de contexto) cuando creo que Wait mantiene a la CPU procesando el hilo actual.

Tenemos ambos porque, aunque puede parecer sensato permitir que otras personas utilicen la CPU mientras no la está utilizando, en la actualidad existe una sobrecarga para el cambio de contexto: dependiendo de cuánto tiempo dura la suspensión, puede ser más costoso en los ciclos de la CPU. para cambiar los hilos de lo que es simplemente hacer que tu hilo no haga nada durante unos pocos ms.

También tenga en cuenta que el sueño obliga a 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 subprocesos.


fuente: http://www.jguru.com/faq/view.jsp?EID=47127

Thread.sleep() envía el hilo actual al estado "No ejecutable" durante un período de tiempo determinado. 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() se activará el hilo de dormir.

Tenga en cuenta que el modo de suspensión es un método estático, lo que significa que siempre afecta al subproceso 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 va a dormir, no el hilo t.

t.suspend() está en desuso. Usándolo es posible detener un hilo que no sea el hilo actual. Un hilo suspendido mantiene todos sus monitores y, como este estado no es interrumpible, es propenso a los interbloqueos.

object.wait() envía el hilo actual al estado "No ejecutable" , como sleep() , pero con un giro. Se llama a la espera en un objeto, no un hilo; Llamamos a este objeto el "objeto de bloqueo". Antes de lock.wait() , el subproceso actual debe sincronizarse en el objeto de bloqueo; wait() 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 original, en espera. Básicamente, wait() / notify() es como sleep() / interrupt() , solo el hilo activo no necesita un puntero directo al hilo inactivo, sino solo al objeto de bloqueo compartido.


¿Esperar () y dormir () diferencias?

Thread.sleep () Una vez completado su trabajo, solo se libera el bloqueo para todos. Hasta que nunca se libere el bloqueo a nadie.

Sleep() take the key, its never release the key to anyone, when its work completed then only its release then only take the key waiting stage threads.

Object.wait () Cuando está en la etapa de espera, se liberará la tecla y se esperarán algunos segundos según el parámetro.

Por ejemplo:

estás tomando el café con la mano derecha, puedes tomar otra persona de la misma mano, cuándo la dejarás y luego solo tomarás otro objeto del mismo tipo aquí. además. esto es dormir () dormiste, no trabajaste, solo estás durmiendo ... igual aquí también.

Espere(). cuando te ponen abajo y tomas otro medio mientras esperas, eso es esperar

estás reproduciendo películas o cualquier cosa en tu sistema, igual que el jugador, no puedes reproducir más de uno a la vez, eso es todo aquí, cuando cierras y eliges otra canción o canción de cualquier persona mientras se llama espera


sleep()El método hace que el hilo actual pase del estado de ejecución al estado de bloqueo durante un tiempo específico. Si el subproceso actual tiene el bloqueo de cualquier objeto, entonces lo mantiene retenido, lo que significa que otros subprocesos no pueden ejecutar ningún método sincronizado en ese objeto de clase.

wait() El método hace que el subproceso actual pase al estado de bloqueo 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).


sleep es un método de Thread , la wait es un método de Object , por lo que wait/notify es una técnica de sincronización de datos compartidos en Java (usando el monitor ), pero la sleep es un método simple de hebra para pausarse.


wait()se da dentro de un método sincronizado mientras que sleep()se da dentro de un método no sincronizado porque el wait()método libera el bloqueo en el objeto pero sleep()o yield()libera el lock().



waitlibera el bloqueo y sleepno lo hace. Un hilo en el estado de espera es elegible para despertarse tan pronto como sea notifyo notifyAllque se llama. Pero en caso de que sleepel hilo mantenga el bloqueo, solo será elegible una vez que finalice el tiempo de suspensión.


Debe llamarse desde el bloque sincronizado: el wait() método siempre se llama desde el bloque sincronizado, es decir, el wait()método debe bloquear el monitor de objetos antes que el objeto en el que se llama. Pero el sleep()método puede llamarse desde un bloque externo sincronizado, es decir, el sleep()método no necesita ningún monitor de objeto.

IllegalMonitorStateException: si wait()se llama al método sin adquirir el bloqueo de objeto, IllegalMonitorStateExceptionse lanza en el tiempo de ejecución, pero el sleep()método nunca lanza dicha excepción.

Pertenece a qué clase: el wait() método pertenece a la java.lang.Objectclase pero el sleep()método pertenece a la java.lang.Threadclase.

Llamado en objeto o hilo: el wait() método se llama en objetos, pero el sleep()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 cuando notify()o notifyAll()método que se llama en ese objeto. Y más tarde, el programador de subprocesos programa ese subproceso para pasar del estado ejecutable al estado ejecutable. cuando sleep()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 suspensión se ha agotado.

Cuando se llama desde el bloque sincronizado: cuando el wait()método se llama subproceso, el objeto se bloquea. Pero el sleep()método cuando se llama desde un bloque sincronizado o un hilo de método no deja el bloqueo del objeto.

Para más Reference


sleep () es un método que se utiliza para mantener el proceso durante unos segundos o el tiempo que deseaba, pero en el caso de que el hilo del método wait () pase al estado de espera y no volverá automáticamente hasta que llamemos a notificar () o notificar a todos ().

La principal diferencia es que wait () libera el bloqueo o el monitor, mientras que sleep () no libera ningún bloqueo o monitor mientras se espera. La espera se utiliza para la comunicación entre subprocesos, mientras que la suspensión se utiliza para introducir una pausa en la ejecución, en general.

Thread.sleep () envía el hilo actual al estado "No ejecutable" durante un período de tiempo determinado. El hilo conserva 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 (), se activará el hilo de dormir. Tenga en cuenta que el modo de suspensión es un método estático, lo que significa que siempre afecta al subproceso 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 va a dormir, no el hilo t.

object.wait () envía el hilo actual al estado "No ejecutable", como sleep (), pero con un giro. Se llama a la espera en un objeto, no un hilo; llamamos a este objeto el "objeto de bloqueo". Antes de llamar a lock.wait (), el subproceso actual debe sincronizarse en el objeto de bloqueo; wait () 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 original, en espera. Básicamente, wait () / notify () es como sleep () / interrupt (), solo el hilo activo no necesita un puntero directo al hilo inactivo, sino solo al objeto de bloqueo compartido.

synchronized(LOCK) { Thread.sleep(1000); // LOCK is held } synchronized(LOCK) { LOCK.wait(); // LOCK is not held }

Vamos a categorizar todos los puntos anteriores:

Call on:

  • esperar (): llamar a un objeto; el hilo actual debe sincronizarse en el objeto de bloqueo.
  • dormir (): llamar a un hilo; siempre ejecutando hilo actualmente.

Synchronized:

  • wait (): cuando varios subprocesos sincronizados acceden al mismo Objeto uno por uno.
  • dormir (): cuando hay varios subprocesos sincronizados, espera el reposo del subproceso.

Hold lock:

  • wait (): libera el bloqueo para que otros objetos tengan la oportunidad de ejecutarse.
  • dormir (): mantener el bloqueo por lo menos t veces si se especifica el tiempo de espera o si alguien interrumpe.

Wake-up condition:

  • espere (): hasta que notifique (), notifique a All () del objeto
  • dormir (): hasta que al menos el tiempo expire o llame a la interrupción ().

Usage:

  • sleep (): para sincronización de tiempo y;
  • wait (): para sincronización de subprocesos múltiples.

Ref: diff sleep y wait


Aquí, wait () estará en el estado de espera hasta que lo notifique otro Hilo, pero mientras que sleep () tendrá algún tiempo ... después de que se transferirá automáticamente al estado Listo ...


Ejemplo sobre el sueño no libera el bloqueo y espera hace

Aquí hay dos clases:

  1. Principal : contiene el método principal y dos hilos.
  2. Singleton : Esta es una clase de singleton con dos métodos estáticos: getInstance () y getInstance (boolean isWait).

    public class Main { private static Singleton singletonA = null; private static Singleton singletonB = null; public static void main(String[] args) throws InterruptedException { Thread threadA = new Thread() { @Override public void run() { singletonA = Singleton.getInstance(true); } }; Thread threadB = new Thread() { @Override public void run() { singletonB = Singleton.getInstance(); while (singletonA == null) { System.out.println("SingletonA still null"); } if (singletonA == singletonB) { System.out.println("Both singleton are same"); } else { System.out.println("Both singleton are not same"); } } }; threadA.start(); threadB.start(); } }

y

public class Singleton { private static Singleton _instance; public static Singleton getInstance() { if (_instance == null) { synchronized (Singleton.class) { if (_instance == null) _instance = new Singleton(); } } return _instance; } public static Singleton getInstance(boolean isWait) { if (_instance == null) { synchronized (Singleton.class) { if (_instance == null) { if (isWait) { try { // Singleton.class.wait(500);//Using wait Thread.sleep(500);// Using Sleep System.out.println("_instance :" + String.valueOf(_instance)); } catch (InterruptedException e) { e.printStackTrace(); } } _instance = new Singleton(); } } } return _instance; } }

Ahora ejecute este ejemplo, obtendrá debajo de la salida:

_instance :null Both singleton are same

Aquí las instancias de Singleton creadas por threadA y threadB son las mismas. Significa que threadB está esperando afuera hasta que threadA libere su bloqueo.

Ahora cambie el Singleton.java comentando Thread.sleep (500); método y descomentación Singleton.class.wait (500); .Aquí debido a Singleton.class.wait (500); El método threadA liberará todos los bloqueos adquiridos y se moverá al estado "No ejecutable", threadB obtendrá cambios para ingresar en el bloque sincronizado.

Ahora corre otra vez:

SingletonA still null SingletonA still null SingletonA still null _instance :com.omt.sleepwait.Singleton@10c042ab SingletonA still null SingletonA still null SingletonA still null Both singleton are not same

Aquí, las instancias de Singleton creadas por threadA y threadB NO son las mismas debido a que threadB consiguió un cambio para ingresar en el bloque sincronizado y, luego de 500 milisegundos, threadA comenzó desde su última posición y creó un objeto Singleton más.


Desde la página de documentación de oracle en el método wait() de Object:

public final void wait()

  1. Hace que el hilo actual espere hasta que otro hilo invoque el notify()método o el notifyAll()método para este objeto. En otras palabras, este método se comporta exactamente como si simplemente realizara la llamada wait(0).
  2. El hilo actual debe poseer el monitor de este objeto. El hilo libera la propiedad de este monitor y espera hasta que otro hilo notifique los hilos que esperan en el monitor de este objeto para que se activen.
  3. Son posibles interrupciones y despertares espurios.
  4. Este método solo debe ser llamado por un hilo que es el propietario del monitor de este objeto.

Este método lanza

  1. IllegalMonitorStateException - si el hilo actual no es el propietario del monitor del objeto.

  2. 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 :

public static void sleep(long millis)

  1. Hace que el subproceso que se está ejecutando en ese momento esté en suspensión (cese temporalmente la ejecución) durante la cantidad especificada de milisegundos, sujeto a la precisión y exactitud de los programadores y temporizadores del sistema.
  2. El hilo no pierde la propiedad de ningún monitor.

Este método arroja:

  1. IllegalArgumentException - si el valor de millis es negativo

  2. InterruptedException- 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ático sleep()(método de clase).


En mi opinión, la principal diferencia entre ambos mecanismos es que el modo de espera / interrupción es la forma más básica de manejar los hilos, mientras que esperar / notificar es una abstracción destinada a facilitar la intercomunicación de los hilos. Esto significa que la suspensión / interrupción puede hacer cualquier cosa, pero que esta tarea específica es más difícil de hacer.

¿Por qué es más conveniente esperar / notificar? Aquí hay algunas consideraciones personales:

  1. 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.

  2. Hace cumplir la sincronización. Porque hace que el programador ajuste la llamada para esperar / notificar en un bloque sincronizado.

  3. Es independiente del origen y número del hilo. Con este enfoque, puede agregar más subprocesos de forma arbitraria sin editar los otros subprocesos o mantener un seguimiento de los existentes. Si utilizaste el modo de suspensión / interrupción, primero deberías mantener las referencias a los hilos de dormir 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 de los clientes en un lugar central (un tablero de corcho, una mesa, etc.). Toca el timbre, y los trabajadores de la cocina vienen a tomar esas peticiones. Una vez que haya preparado el curso, 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.


  • El método wait(1000)hace que el hilo actual duerma hasta un segundo .
    • Un hilo podría dormir menos de 1 segundo si recibe la llamada al método notifyonotifyAll .
  • La llamada a Thread.sleep()hace que el hilo actual se duerma durante exactamente 1 segundo .
    • También el hilo de dormir no mantiene bloqueado ningún recurso . Pero el hilo de espera lo hace.