English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
El mecanismo de interrupción de la hebra proporciona un método para despertar a la hebra de espera en estado de bloqueo, intentando interrumpir el flujo de procesamiento actual de la hebra de destino para que responda a un nuevo comando. Java deja esta libertad a los desarrolladores, y deberíamos aprovecharla bien.
Hoy hablaremos sobre el mecanismo de interrupción de las hebras en Java.
El mecanismo de interrupción de la hebra proporciona un método, que tiene dos usos comunes:
Despierta a la hebra de espera en estado de bloqueo y realiza el tratamiento correspondiente de 'interrupción controlada'.
Intentar informar a la hebra de destino: interrumpa el flujo de procesamiento actual y responde a un nuevo comando.
Por ejemplo, en el primer uso, vea el siguiente código:
synchronized (lock) { try { while (!check()) { lock.wait(1000); } } e.printStackTrace(); } }
Este código utiliza wait proporcionado por Java/El mecanismo notify, cuando la hebra ejecuta lock.wait() se bloquea, hay tres situaciones que hacen que la hebra recupere su ejecución.
1tiempo de espera 1000ms finaliza, ejecutando correctamente la próxima instrucción.
2otra hebra ejecuta el siguiente código para activar
synchronized (lock) { lock.notifyAll(); // o lock.notify(); }
Esto también se ejecutará correctamente la próxima instrucción.
3otra hebra requiere que la hebra en espera 'se interrumpa'
// Obtener la referencia de la hebra en espera Thread a; a.interrupt();
La hebra 'interrumpida' a, lanzará la excepción InterruptedException en lock.wait().
En resumen, puedes considerar que object.wait() está haciendo lo siguiente internamente:
boolean checkTimeout = timeout > 0; Thread current = Thread.currentThread(); lock.addWaiter(current); while (!current.isNotified()) { if (current.isInterrupted()) { current.clearInterrupted(); throw new InterruptedException(); } if (checkTimeout) { if (timeout == 0) break; timeout--; } }
Esto no es completamente preciso, porque wait no utiliza este método de 'busqueda activa' para hacer comprobaciones, pero la lógica de juicio sobre el marcador es correcta.
Vamos a explorar la operación mencionada anteriormente de 'interrupción manual'
// sun.nio.ch.Interruptible public interface Interruptible { void interrupt(Thread var1); } // java.lang.Thread private volatile Interruptible blocker; private final Object blockerLock = new Object(); public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interrupt0(); b.interrupt(this); return; } } interrupt0(); } // Sólo para establecer la bandera de interrupción private native void interrupt0();
Se puede ver que thread.interrupt() primero verifica los permisos, luego llama realmente a interrupt0() para establecer la bandera de interrupción del hilo, y si el hilo actual tiene Interruptible de nio, también lo invocará.
Atención, interrupt0() solo establece la bandera de interrupción del hilo.
Cuando una hebra no está bloqueada, no está en áreas como object.wait(), thread.join(), Thread.sleep() que no están bajo el control lógico del programa Java, ¿qué sucederá? La respuesta es que no sucederá nada, si la hebra ha sido interrumpida o no solo se puede saber mediante la verificación activa del indicador de interrupción.
¿Cómo verificarlo? Thread expone dos interfaces, Thread.interrupted() y thread.isInterrupted().
// java.lang.Thread public static boolean interrupted() { return currentThread().isInterrupted(true); } public boolean isInterrupted() { return isInterrupted(false); } private native boolean isInterrupted(boolean clearInterrupted);
Se puede ver que ambos dependen internamente de isInterrupted(boolean), que devuelve si la hebra ha sido interrumpida y, según sea necesario, borra el indicador de interrupción.
Cuando una función de llamada causará bloqueo, las funciones de la biblioteca de Java en el punto de firma de bloqueo marcan throws InterruptedException y requieren que se escriba try catch para manejar la interrupción.
Cuando una hebra se bloquea, como se mencionó anteriormente, Java detecta el indicador de interrupción, lo borra primero y luego lanza InterruptedException.
// java.lang.Object public final void wait() throws InterruptedException { wait(0); } public final native void wait(long timeout) throws InterruptedException;
Si una hebra recibe InterruptedException y luego sigue ejecutando código que causará bloqueo, continuará bloqueándose como si nada hubiese pasado. ¡Porque Java borra internamente el indicador de interrupción!
es común escribir los siguientes tres tipos de código para manejar InterruptedException:
dejar que InterruptedException sea procesado en el nivel superior.
public void foo() throws InterruptedException { synchronized (lock) { lock.wait(); } }
Reconfigura el marcador de interrupción al encontrar InterruptedException.
try { synchronized (lock) { lock.wait(); } } Thread.currentThread().interrupt(); //break; }
Primero, termina la tarea actual, luego lanza nuevamente InterruptedException.
public void bar() throws InterruptedException { InterruptedException ie = null; boolean done = false; while (!done) { synchronized (lock) { try { lock.wait(); } ie = e; continue; } } done = true; } if (ie != null) { throw ie; } }
Si un hilo ignora el signo de interrupción y InterruptedException, aún puede ejecutarse bien. Pero esto va en contra de la intención original de diseñar multihilos, queremos que los hilos cooperen de manera armoniosa y有序 para lograr funciones específicas, por lo tanto, el hilo controlado debe responder a la interrupción. Java deja a los desarrolladores esta libertad, deberíamos aprovecharla adecuadamente.
Esto es todo el contenido relacionado con el mecanismo de interrupción de hilos Java que les he presentado esta vez. Si aún tienen alguna duda, pueden discutirlo en la zona de comentarios a continuación. Gracias por su apoyo a la教程.
Declaración: El contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha editado artificialmente y no asume responsabilidades legales relacionadas. Si encuentra contenido sospechoso de copyright, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @ para denunciar y proporcione evidencia. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción.)