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?

¿Fue útil?

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 con sleep () , el sistema operativo no & # 8217; t   incluso intente programar su tarea a menos que alguien llame a notify () (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 un yield () 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
  1. 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 () lanza InterruptedException {// ...}
  4. wait () debe ser notificado por los métodos notify () o notifyAll () .
  5. El método
  6. wait () debe llamarse desde un bucle para tratar las falsas alarmas.

  7. El método
  8. wait () debe llamarse desde el contexto sincronizado (es decir, método o bloque sincronizado), de lo contrario arrojará IllegalMonitorStateException

sleep ()

    El método
  1. 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) lanza InterruptedException {// ...}
  4. después de la cantidad de tiempo especificada, sleep () se completa.
  5. sleep () mejor no llamar desde el bucle (es decir, ver el código a continuación ).
  6. Se puede llamar a
  7. 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    
}

 transición de hilo a diferentes estados de hilo

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:

  1. 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)
  2. 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)
  3. 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)
  4. 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
  5. 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 de Object y sleep () es un método estático de Hilo .

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

  • wait () se usa para la comunicación entre subprocesos mientras que sleep () se usa para introducir una pausa en la ejecución, generalmente.

  • Se debe llamar a
  • wait () desde la sincronización interna o de lo contrario obtenemos una IllegalMonitorStateException , mientras que se puede llamar a sleep () en cualquier lugar.

  • Para volver a iniciar un hilo desde wait () , debe llamar a notify () o notifyAll () . En cuanto a sleep (), 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 a t.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 " ,   como sleep () , 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 que lock.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 a lock.notify () . Esto despierta el original,   hilo de espera Básicamente, wait () / notify () es como    sleep () / 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

Los métodos

wait y sleep son muy diferentes:

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.

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

  2. sleep () permite que el hilo pase al estado sleep durante x milisegundos.
    Cuando un hilo pasa al estado de suspensión no libera el bloqueo .

  3. wait () permite que el hilo libere el bloqueo y pasa al estado suspendido .
    Este hilo estará activo cuando un método notify () o notifAll () sea pidió el mismo objeto.

Una gran diferencia potencial entre dormir / interrumpir y esperar / notificar es que

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.

El método

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.

El método

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:

  1. Impone la centralización. Permite coordinar la comunicación entre un grupo de hilos con un solo objeto compartido. Esto simplifica mucho el trabajo.

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

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

  1. Principal : contiene el método principal y dos hilos.
  2. 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()
  1. Hace que el hilo actual espere hasta que otro hilo invoque el método notify () o el método notifyAll () 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 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
  3. interrupciones y espurias despiertas son posibles
  4. Este método solo debe ser llamado por un hilo que sea el propietario del monitor de este objeto

Este método arroja

  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.

De la página de documentación de Oracle en método sleep () de la clase Thread :

public static void sleep(long millis)
  1. 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.
  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).

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 .
  • 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í.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top