Diferencia entre wait () y sleep ()
-
10-07-2019 - |
Pregunta
¿Cuál es la diferencia entre un wait ()
y sleep ()
en subprocesos?
Entiendo que un subproceso wait ()
-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?
Solución
A wait
puede "despertarse" por otro hilo llamando a notificar
en el monitor que se está esperando mientras que un sleep
no puede. También debe esperar
(y notificar
) en un bloque sincronizado
en el objeto del 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 hacer
synchronized (mon) { mon.notify(); }
(en el mismo objeto mon
) y el primer hilo (suponiendo que sea el único hilo que espera en el monitor) se activará.
También puede llamar a notifyAll
si hay más de un hilo esperando en el monitor; esto despertará a todos ellos . Sin embargo, solo uno de los hilos podrá agarrar el monitor (recuerde que wait
está en un bloque sincronizado
) y continúe; los demás se bloquearán hasta pueden adquirir el bloqueo del monitor.
Otro punto es que llama a wait
en Object
en sí (es decir, espera en el monitor de un objeto) mientras que llama a sleep
en Tema
.
Sin embargo, otro punto es que puede obtener despertadores espurios de wait
(es decir, el hilo que está esperando se reanuda sin razón aparente). Debe siempre esperar
mientras gira en alguna condición de la siguiente manera:
synchronized {
while (!condition) { mon.wait(); }
}
Otros consejos
Una diferencia clave que aún no se menciona es que, mientras duerme, un subproceso no libera los bloqueos que contiene, mientras que la espera libera el bloqueo del objeto que wait ()
llamado.
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
Encontré esta publicación útil. Pone la diferencia entre Thread.sleep ()
, Thread.yield ()
y Object.wait ()
en términos humanos. Para citar:
Todo finalmente llega al programador del sistema operativo, que reparte tiempos de espera para procesos y subprocesos.
sleep (n)
dice & # 8220; he terminado con mi timeslice, y por favor no me des otro por al menos n milisegundos. & # 8221; El sistema operativo ni siquiera intenta programar el hilo de dormir hasta que haya pasado el tiempo solicitado.
yield ()
dice & # 8220; he terminado con mi parte temporal, pero todavía tengo trabajo para do. & # 8221; El sistema operativo es libre de darle inmediatamente al hilo otra división de tiempo, o para dar otro hilo o procesar a la CPU el hilo que cede simplemente me rendí.
wait ()
dice & # 8220; he terminado con mi timeslice. No me des otro división de tiempo hasta que alguien llame a notify (). & # 8221; Al igual que consleep ()
, el sistema operativo no & # 8217; t incluso intente programar su tarea a menos que alguien llame anotify ()
(o uno de se producen algunos otros escenarios de activación).Los subprocesos también pierden el resto de su segmento de tiempo cuando realizan bloqueo de IO y en algunas otras circunstancias. Si un hilo funciona a través de todo el segmento de tiempo, el sistema operativo toma el control por la fuerza aproximadamente si se hubiera llamado a
yield ()
, para que se puedan ejecutar otros procesos.Rara vez necesita
yield ()
, pero si tiene una aplicación computacional con límites de tareas lógicas, insertando unyield ()
podría mejorar el sistema capacidad de respuesta (a expensas del tiempo & # 8212; cambios de contexto, incluso solo al sistema operativo y viceversa, no están libres). Mide y prueba contra tus objetivos preocuparse, como siempre.
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 Thread a dormir como estaba antes, simplemente 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 usa 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 considerarlo como un patrón de publicación-suscripción ( wait
== subscribe y notify ()
== Publicar). Básicamente, utilizando la notificación () está enviando un mensaje (que incluso podría no recibirse y normalmente no le importa).
Para resumir, normalmente usa 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 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.
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 (funcionamiento interno, solo juegue un poco para comprender mejor).
wait ()
-
El método
-
wait ()
libera el bloqueo. -
wait ()
es el método de la claseObject
. -
wait ()
es el método no estático -public final void wait () lanza InterruptedException {// ...}
-
wait ()
debe ser notificado por los métodosnotify ()
onotifyAll ()
.
El método wait ()
debe llamarse desde un bucle para tratar las falsas alarmas.
El método wait ()
debe llamarse desde el contexto sincronizado (es decir, método o bloque sincronizado), de lo contrario arrojaráIllegalMonitorStateException
sleep ()
-
El método
-
sleep ()
no libera el bloqueo. -
sleep ()
es el método de la clasejava.lang.Thread
. -
sleep ()
es el método estático -public static void sleep (long millis, int nanos) lanza InterruptedException {// ...}
- después de la cantidad de tiempo especificada,
sleep ()
se completa. -
sleep ()
mejor no llamar desde el bucle (es decir, ver el código a continuación ).
Se puede llamar a -
sleep ()
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
synchronized(monitor){
while(condition == true){
monitor.wait() //releases monitor lock
}
Thread.sleep(100); //puts current thread on Sleep
}
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 espera () y suspensión ():
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();
}
Deje en claro algunas notas clave:
- Llamada :
- wait (): Llama al hilo actual que contiene HandObject Object
- sleep (): Llamada al subproceso ejecutar tarea obtener cerveza (es el método de clase, así que afecta el subproceso actual)
- Sincronizado :
- wait (): cuando se sincroniza el acceso a varios subprocesos al mismo objeto (HandObject) (cuando se necesita comunicación entre más de un subproceso (subproceso ejecutar codificación, subproceso ejecutar get beer) acceso en el mismo objeto HandObject)
- sleep (): cuando la condición de espera para continuar se ejecuta (Esperando cerveza disponible)
- Bloqueo de retención :
- wait (): suelta el bloqueo para que otro objeto tenga oportunidad de ejecutarse (HandObject es gratis, puedes hacer otro trabajo)
- sleep (): mantener el bloqueo durante al menos t veces (o hasta que se interrumpa) (Mi trabajo aún no termina, continuaré manteniendo el bloqueo y esperando alguna condición para continuar)
- Condición de activación :
- wait (): hasta que call notify (), notifyAll () desde el objeto
- sleep (): hasta que caduque al menos el tiempo o se interrumpa la llamada
- Y el último punto es usar cuando como estani indican:
normalmente usa sleep () para sincronización de tiempo y wait () para sincronización multihilo.
Corrígeme si me equivoco.
Diferencia entre wait () y sleep ()
-
La diferencia fundamental es que
wait ()
es deObject
ysleep ()
es un método estático deHilo
. -
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.
Se debe llamar a wait ()
desde la sincronización interna o de lo contrario obtenemos unaIllegalMonitorStateException
, mientras que se puede llamar asleep ()
en cualquier lugar.- Para volver a iniciar un hilo desde
wait ()
, debe llamar anotify ()
onotifyAll ()
. En cuanto asleep (),
el hilo se inicia después de un intervalo de tiempo especificado.
Similitudes
- Ambos hacen que el hilo actual pase al estado No ejecutable .
- Ambos son métodos nativos .
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 usa 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 el caso del hilo del método wait ()
pasa al estado de espera y no volverá automáticamente hasta que llamemos al método notify ()
(o notifyAll ()
si tiene más de un hilo en estado de espera y desea despertar todos esos hilos). Y necesita sincronización o bloqueo de objeto o bloqueo de clase para acceder a los métodos wait ()
o notify ()
o 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 despertar 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 que desea. Debido a que no necesita provocar ningún método notify ()
o notifyAll ()
para recuperar ese hilo. O no necesita ningún otro hilo para volver a llamar ese hilo. Por ejemplo, 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, puedes mencionar el método sleep ()
.
Y una diferencia más importante que a menudo se pregunta en las entrevistas: sleep ()
pertenece a la clase Thread
y wait ()
pertenece a < code> Object class.
Estas son todas las diferencias entre sleep ()
y wait ()
.
Y existe una similitud entre ambos métodos: ambos son enunciados comprobados, por lo que debe intentar atrapar o lanzar para acceder a estos métodos.
Espero que esto te ayude.
fuente: http://www.jguru.com/faq/view. jsp? EID = 47127
Hilo .sleep ()
envía el hilo actual al estado " No ejecutable " por una cierta cantidad de 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 at.interrupt ()
despertará el hilo dormido.Tenga en cuenta que el sueño es un método estático, lo que significa que siempre afecta el hilo actual (el que está ejecutando el método de suspensión). UNA 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.
t .suspend ()
está en desuso. Al usarlo es posible detener un hilo otro que el hilo actual. Un hilo suspendido mantiene todos sus monitores y dado que este estado no es interrumpible, es propenso a un punto muerto.
objeto .wait ()
envía el hilo actual al estado " No ejecutable " , comosleep ()
, pero con un giro. La espera se llama a un objeto, no a un hilo; llamamos a este objeto el "objeto de bloqueo". Antes de quelock.wait ()
sea llamado, el hilo actual debe sincronizarse en el objeto de bloqueo;wait ()
luego libera este bloqueo y agrega el hilo a la " lista de espera " asociado con la cerradura. Más tarde, otro hilo puede sincronizarse en el mismo objeto de bloqueo y llame alock.notify ()
. Esto despierta el original, hilo de espera Básicamente,wait ()
/notify ()
es comosleep ()
/interrupt ()
, solo el hilo activo no necesita un directo puntero al hilo inactivo, pero solo al objeto de bloqueo compartido.
Esperar y dormir son dos cosas diferentes:
- En
sleep ()
el hilo deja de funcionar durante la duración especificada. - En
wait ()
el hilo deja de funcionar hasta que el objeto que se está esperando es notificado, generalmente por otros hilos.
sleep
es un método de Thread
, wait
es un método de Object
, entonces wait / notify
es una técnica de sincronización de datos compartidos en Java (usando monitor ), pero sleep
es un método simple de subproceso para pausarse.
sleep () es un método que se utiliza para mantener 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 llegará volver automáticamente hasta que llamemos a notify () o notifyAll ().
La gran diferencia es que wait () libera el bloqueo o monitor mientras el modo 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 un período de 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.
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
Deje categorizar todos los puntos anteriores:
Llamar al:
- wait (): Llamar a un objeto; el hilo actual debe sincronizarse en el objeto de bloqueo.
- sleep (): Llamar a un hilo; siempre ejecutando hilo actualmente.
Synchronized:
- wait (): cuando varios hilos sincronizados acceden al mismo objeto uno por uno.
- sleep (): cuando se sincronizan varios subprocesos, espere el reposo del subproceso.
Bloqueo de retención:
- wait (): suelte el bloqueo para que otros objetos tengan la oportunidad de ejecutarse.
- sleep (): mantenga el bloqueo durante al menos t veces si el tiempo de espera especificado o alguien interrumpe.
Condición de activación:
- espera (): hasta que la llamada notifique (), notifique a Todos () desde el objeto
- sleep (): hasta que caduque al menos el tiempo o llame a interrupt ().
Usage:
- sleep (): para sincronización horaria y;
- wait (): para sincronización multihilo.
Ref: diff sleep
y esperar
wait
y sleep
son muy diferentes:
-
dormir
no tiene forma de "despertarse", - mientras que
esperar tiene una forma de "despertar" durante el período de espera, mediante otro subproceso que llama anotificar
onotifyAll
.
Ahora que lo pienso, los nombres son confusos a ese respecto; sin embargo, sleep
es un nombre estándar y wait
es como el WaitForSingleObject
o WaitForMultipleObjects
en la API de Win.
En palabras simples, esperar es esperar hasta que otro hilo te invoque mientras que dormir es "no ejecutes la siguiente declaración" por 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. :)
De esta publicación: http://javaconceptoftheday.com / diferencia-entre-esperar-y-dormir-métodos-en-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) Otros hilos no pueden despertar los hilos dormidos. Si lo hace, el hilo arrojará InterruptedException.
5) Para llamar al método sleep (), el hilo no necesita tener bloqueo de objeto.
wait ()
es un método de la claseObject
.
sleep ()
es un método de claseThread
.sleep ()
permite que el hilo pase al estadosleep
durante x milisegundos.
Cuando un hilo pasa al estado de suspensiónno libera el bloqueo
.wait ()
permite que el hilo libere el bloqueo ypasa al estado suspendido
.
Este hilo estará activo cuando un métodonotify ()
onotifAll ()
sea pidió el mismo objeto.
Una gran diferencia potencial entre dormir / interrumpir y esperar / notificar es que
- llamando a
interrupt ()
durantesleep ()
siempre arroja una excepción (por ejemplo, InterruptedException ), mientras que - llamando a
notifique ()
durantewait ()
no lo hace.
Generar una excepción cuando no es necesario es ineficiente. Si tiene hilos que se comunican entre sí a una velocidad alta, generaría muchas excepciones si llamara a interrupción todo el tiempo, lo que es un desperdicio total de CPU.
Estás en lo correcto: Sleep () hace que ese hilo '' duerma '' y la CPU se apagará y procesará otros subprocesos (también conocido como cambio de contexto) cuando creo que Wait mantiene a la CPU procesando el subproceso actual.
Tenemos ambos porque, aunque puede parecer sensato dejar 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 dura el sueño, puede ser más costoso en ciclos de 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.
Los métodos se usan para diferentes cosas.
Thread.sleep(5000); // Wait until the time has passed.
Object.wait(); // Wait until some other thread tells me to wake up.
Thread.sleep (n) puede interrumpirse, pero Object.wait () debe ser notificado.
Es posible especificar el tiempo máximo de espera: Object.wait (5000)
para que sea posible usar wait
para, por ejemplo, sleep
pero luego tienes que molestarte con las cerraduras.
Ninguno de los métodos usa 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 ...
Aquí wait () estará en el estado de espera hasta que se notifique por otro Thread pero donde como sleep () tendrá algún tiempo ... después de eso se transferirá automáticamente al estado Listo ...
¿Espera () y sleep () diferencias?
Thread.sleep () Una vez que se completa 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 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 otro cualquiera de la misma mano, cuando lo dejes, solo tomarás otro objeto del mismo tipo aquí. además. esto es dormir () duermes, no trabajaste, solo duermes ... lo mismo aquí también.
espera (). cuando te desaniman y tomas otro significado mientras esperas, eso es esperar
estás reproduciendo una película o cualquier cosa en tu sistema igual que el reproductor, no puedes reproducir más de una a la vez, eso es aquí, cuando cierras y eliges otra película o canción cualquiera mientras se llama esperar
wait
libera el bloqueo y sleep
no. Un hilo en estado de espera es elegible para despertarse tan pronto como se llame a notify
o notifyAll
. Pero en el caso de sleep
, el hilo mantiene el bloqueo y solo será elegible una vez que termine el tiempo de espera.
sleep ()
hace que el hilo actual se mueva 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 ()
hace que el hilo actual entre en estado de bloque por un tiempo especificado o hasta que se notifique, pero en este caso el hilo libera el bloqueo del objeto (lo que significa que otros hilos puede ejecutar cualquier método sincronizado del objeto que realiza la llamada.
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:
Impone 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 hilos arbitrariamente sin editar los otros hilos o hacer 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 toca el timbre nuevamente para que los camareros estén al tanto y se los lleven a los clientes.
El ejemplo sobre el sueño no libera el bloqueo y la espera sí
Aquí hay dos clases:
- Principal : contiene el método principal y dos hilos.
Singleton : esta es una clase 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á el siguiente resultado:
_instance :null
Both singleton are same
Aquí las instancias Singleton creadas por threadA y threadB son iguales. Significa que threadB está esperando afuera hasta que threadA lo libere.
Ahora cambie Singleton.java comentando Thread.sleep (500); método y descomentar Singleton.class.wait (500); . Aquí por Singleton.class.wait (500); El hilo de método A liberará todos los bloqueos de adquisición y se moverá a & # 8220; Non Runnable & # 8221; estado, se cambiará threadB para ingresar en bloque sincronizado.
Ahora ejecute nuevamente:
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 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.
Debe llamarse desde el bloque sincronizado: el método wait ()
siempre se llama desde el bloque sincronizado, es decir, el método wait ()
necesita bloquear el objeto supervisar antes del objeto en el que se llama. Pero el método sleep ()
se puede llamar desde un bloque sincronizado externo, es decir, el método sleep ()
no necesita ningún monitor de objetos.
IllegalMonitorStateException: si se llama al método wait ()
sin adquirir el bloqueo del objeto que IllegalMonitorStateException
se lanza en tiempo de ejecución, pero sleep ( )
el método nunca arroja tal excepción.
Pertenece a qué clase: el método wait ()
pertenece a la clase java.lang.Object
pero sleep () pertenece a la clase
java.lang.Thread
.
Llamado en objeto o hilo: el método wait ()
se llama en los objetos pero el método sleep ()
se llama en los Hilos, no en los objetos.
Estado de subproceso: cuando se llama al método wait ()
en el objeto, el monitor del objeto retenido pasa del estado de ejecución al estado de espera y puede volver al estado de ejecución solo se indica cuando se llama al método notify ()
o notifyAll ()
en ese objeto. Y luego, el planificador de subprocesos programa ese subproceso para pasar del estado ejecutable al estado en ejecución.
cuando se invoca sleep ()
en el subproceso, pasa del estado de ejecución al estado de espera y puede volver al estado de ejecución cuando se agota el tiempo de suspensión.
Cuando se llama desde el bloque sincronizado: cuando se llama al método wait ()
, el hilo deja el bloqueo del objeto. Pero el método sleep ()
cuando se llama desde un bloque sincronizado o un hilo de método no deja el bloqueo de objetos.
Para más Referencia
De la página de documentación de Oracle en wait () método de Object
:
public final void wait()
- Hace que el hilo actual espere hasta que otro hilo invoque el método
notify ()
o el métodonotifyAll ()
para este objeto. En otras palabras, este método se comporta exactamente como si simplemente realizara la llamadawait (0)
. - El hilo actual debe poseer el monitor de este objeto. El subproceso libera la propiedad de este monitor y espera hasta que otro subproceso notifique a los subprocesos que esperan que el monitor de este objeto se active
- interrupciones y espurias despiertas son posibles
- Este método solo debe ser llamado por un hilo que sea el propietario del monitor de este objeto
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.
De la página de documentación de Oracle en método sleep () de la clase Thread
:
public static void sleep(long millis)
- 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.
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ático sleep ()
(método de clase).
wait ()
se proporciona dentro de un método sincronizado
mientras que sleep ()
se proporciona dentro de un método no sincronizado porque el método wait ()
libera el bloqueo del objeto pero sleep ()
o < code> yield () libera el lock ()
.
esperar con un valor de tiempo de espera puede activarse al transcurrir el valor de tiempo de espera o notificar lo que sea anterior (o interrumpir también), mientras que, un sueño se activa con el valor de tiempo de espera transcurrido o interrumpir lo que sea anterior. wait () sin valor de tiempo de espera esperará para siempre hasta que se notifique o se interrumpa
- 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 el
notify ()
onotifyAll ()
llamada al método.
- Un hilo podría dormir menos de 1 segundo si recibe el
- La llamada a
sleep (1000)
hace que el hilo actual se suspenda durante exactamente 1 segundo .- También el hilo dormido no mantiene bloqueado ningún recurso . Pero el hilo de espera sí.