¿Cuál es la diferencia entre suspensión y espera de Java?
La diferencia entre dormir() y esperar()
El subproceso múltiple en Java es un mecanismo preventivo en lugar de un mecanismo de tiempo compartido. Los subprocesos tienen principalmente los siguientes estados: ejecutable, en ejecución, bloqueado y muerto. El mecanismo preventivo significa que hay varios subprocesos en estado ejecutable, pero solo se está ejecutando un subproceso.
Cuando varios subprocesos acceden a datos compartidos, es necesario sincronizarlos. Comparación de varios métodos principales en hilos:
Métodos de clase de hilo: dormir(), rendimiento(), etc.
Métodos de objeto: esperar(), notificar(), etc.
Cada objeto tiene un bloqueo de máquina para controlar el acceso sincrónico. La palabra clave sincronizada puede interactuar con el bloqueo de la máquina del objeto para lograr la sincronización del subproceso.
Dado que el método sleep() es un método de la clase Thread, no puede cambiar el bloqueo de la máquina del objeto. Entonces, cuando se llama a dormir () en un método sincronizado, aunque el subproceso duerme, el bloqueo de la máquina del objeto no se libera y otros subprocesos aún no pueden acceder al objeto. El método wait() liberará el bloqueo de la máquina mientras el subproceso duerme y otros subprocesos podrán acceder al objeto.
El método Yield() detiene el hilo actual y permite que se ejecuten hilos de igual prioridad. Si no hay subprocesos con la misma prioridad, el método Yield() no funcionará.
El signo del final de un hilo es: el final del método run().
La señal de que se libera un bloqueo de la máquina es: el final del bloque o método sincronizado.
Método Wait() y método notify(): cuando un hilo ejecuta el método wait() (el hilo duerme y libera el bloqueo de la máquina), ingresa a un grupo de espera relacionado con el objeto. tiempo, el bloqueo de la máquina del objeto se pierde. Cuando se despierta mediante un método notify (), los subprocesos en el grupo de espera se colocan en el grupo de bloqueo. El hilo obtiene el bloqueo de la máquina del grupo de bloqueos y luego regresa al sitio de interrupción antes de esperar ().
El método join() hace que el hilo actual se detenga y espere hasta que finalice otro hilo que llama al método join.
Vale la pena señalar que el hilo no necesariamente se ejecuta inmediatamente después de ser activado, sino que ingresa a la cola de hilos ejecutables.
***Mismo punto: ambos están en un entorno de subprocesos múltiples y pueden bloquear la cantidad especificada de milisegundos en el punto de llamada del programa y regresar.
Diferencias: Thread.sleep(long) no se puede llamar bajo un bloque sincronizado, y el uso de Thread.sleep() no perderá el bloqueo de sincronización (monitor) del hilo actual en ningún objeto; p>
object.wait(long) debe usarse en un bloque sincronizado. Después de llamarlo, el monitor del objeto se perderá. La ventaja de esto es que no afecta a otros subprocesos que operan en el objeto.
Da un ejemplo de Java.util.Timer para ilustrarlo.
private void mainLoop() {
mientras (verdadero) {
....
sincronizado(cola) { p>
p>
.....
if (!taskFired) // La tarea aún no se ha activado; espera
queue.wait(executionTime - currentTime);
p>}
}
¿Por qué usamos queue.wait() en lugar de Thread.sleep() aquí? abandone temporalmente el bloqueo de objetos de la cola. Permita que otros subprocesos realicen algunas operaciones de sincronización.
Por ejemplo:
programación nula privada (tarea TimerTask, mucho tiempo, largo período) {
sincronizado(cola) {
...
queue.add(task);
}
}
Pero como se mencionó en el artículo anterior, el requisito previo para usar queue.wait(long ) La condición es que el tiempo de ejecución de la acción sched() sea muy corto; de lo contrario, si es muy largo, queue.wait() no podrá activarse a tiempo.
(2)
Como se mencionó anteriormente, el mecanismo de espera/notificación también se analiza. Thread también tiene un método estático sleep(), que también puede hacer que el hilo se detenga por un tiempo. período de tiempo. La diferencia entre dormir y esperar es que dormir no libera el bloqueo y la pausa del sueño es diferente de la pausa de la espera. obj.wait hará que el hilo ingrese a la colección de espera del objeto obj y espere a que se active.
Sin embargo, tanto wait() como sleep() pueden interrumpir el estado de pausa del hilo a través del método interrupt(), lo que hace que el hilo arroje inmediatamente InterruptedException.
Si el subproceso A quiere finalizar el subproceso B inmediatamente, puede llamar al método de interrupción en la instancia del subproceso correspondiente al subproceso B. Si el hilo B está esperando/suspendiendo/uniéndose en este momento, el hilo B lanzará inmediatamente InterruptedException y regresará directamente en catch() {} para finalizar el hilo de forma segura.
Cabe señalar que InterruptedException es lanzada internamente por el hilo mismo, no por el método interrupt(). Cuando se llama a interrupción () en un hilo, si el hilo está ejecutando código normal, el hilo no arrojará InterruptedException en absoluto. Sin embargo, una vez que el hilo ingresa a wait()/sleep()/join(), se generará una InterruptedException inmediatamente.
No se recomiendan los métodos sleep(), suspend() y resume(). Se recomienda utilizar wait(), notify() y notifyAll().
El método sleep() es un método que detiene el hilo durante un período de tiempo. Una vez transcurrido el intervalo de suspensión, el subproceso no necesariamente reanuda la ejecución de inmediato. Esto se debe a que en ese momento, es posible que otros subprocesos se estén ejecutando y no estén programados para abandonar la ejecución, a menos que
(a) el subproceso "activado" tenga una prioridad más alta.
(b) El hilo en ejecución está bloqueado por otros motivos.
Wait() es una interacción de hilo. Si el hilo emite una llamada de espera() a un objeto de sincronización x, el hilo suspenderá la ejecución y el objeto llamado entrará en estado de espera hasta que se despierte o el hilo. el tiempo de espera expira.
Cuando se llama a wait(), el subproceso liberará el "indicador de bloqueo" que ocupa, de modo que otros subprocesos puedan utilizar otros datos sincronizados en el objeto donde se encuentra el subproceso.
Waite() y notify() operan en el "indicador de bloqueo" del objeto, por lo que deben llamarse en una función sincronizada o en un bloque sincronizado. Si se llama en una función no sincronizada o en un bloque no sincronizado, aunque se puede compilar, se producirá una excepción IllegalMonitorStateException en tiempo de ejecución.