El mecanismo de interrupción de subprocesos proporciona un método para despertar un hilo de una espera de bloqueo, tratando de interrumpir el flujo de procesamiento existente del hilo de destino y responder a nuevos comandos. Java deja esta libertad para los desarrolladores, y debemos hacerle un buen uso.
Hoy hablaremos sobre el mecanismo de interrupción de los hilos de Java.
El mecanismo de interrupción de subprocesos proporciona un método que tiene dos usos comunes:
Despertar el hilo del bloqueo de la espera y hacer el procesamiento correspondiente de "interrupción controlada".
Intente informar el hilo de destino: interrumpir el flujo de procesamiento existente y responda a nuevos comandos.
Tome el primer propósito como ejemplo, consulte el siguiente código:
sincronizado (bloqueo) {try {while (! check ()) {Lock.wait (1000); }} catch (InterruptedException e) {E.PrintStackTrace (); }}Este código utiliza el mecanismo Wait/Notify proporcionado por Java. La ejecución de subprocesos de Lock.Wait () bloqueará. Hay tres situaciones para restaurar el hilo para ejecutar.
1. Tiempo de espera 1000ms termina, y el siguiente código se ejecuta normalmente.
2. Otro hilo ejecuta el siguiente código para despertarse activamente
sincronizado (bloqueo) {Lock.notifyAll (); // o bloquear.notify ();}Esto también ejecutará el siguiente código normalmente.
3. Otro hilo que debe esperar es "interrupción"
// Obtener la referencia al hilo de espera en espera A; A.interrupt ();
El hilo A que está "interrumpido" lanzará una excepción de InterruptedException en Lock.Wait ().
Para resumir, puede pensar que Object.Wait () está haciendo estas cosas internamente:
boolean checktimeout = timeOut> 0; hilo actual = hilo.currentThread (); bloqueo.addwaiter (current); while (! current.isNotified ()) {if (current.isinterrupted ()) {current.clearinterrupted (); tirar nueva interrupciónxception (); } if (checktimeout) {if (timeOut == 0) ruptura; se acabó el tiempo--; }}Esto no es completamente exacto, porque Wait no usa este método de "encuesta ocupada" para verificar, pero la lógica de juzgar bits de bandera es correcta.
Comencemos con la operación de "interrupción manual" mencionada anteriormente
// Sun.nio.ch.interruptiblePublic Interface Interruptible {Void Interrupt (Thread Var1);} // java.lang.threadPrivate Volatile Interruptible Blocker; private final Objectlock = new Object (); public void Interrupt () {if (this! = Thread.CurrentThread ()) checkAcess (); Sincronizado (BlockerLock) {Interruptible B = Blocker; if (b! = null) {interrupt0 (); B. Interrupción (esto); devolver; }} interrupt0 ();} // Solo para establecer la interrupción national national interrupt0 ();Se puede ver que Thread.interrupt () los primeros permisos de jueces, y luego llaman a Interrupt0 () para establecer el indicador de interrupción del hilo. Si el hilo actual tiene la interrupción de NIO, también volverá a llamar.
Tenga en cuenta que interrupt0 () solo establece el indicador de interrupción del hilo.
¿Qué sucede cuando un hilo no está bloqueando y no está en áreas que no están controladas por la lógica del programa Java, como Object.Wait (), Thread.Join (), Thread.sleep ()? La respuesta es que no sucederá nada, y si el hilo está interrumpido solo puede ser conocido revisando activamente la bandera de interrupción.
¿Cómo comprobar? El hilo expone dos interfaces, thread.interrupted () y thread.isinterrupted ().
// java.lang.threadpublic static boolean interrumped () {return currentThread (). isinterrupted (true);} public boolean isinterrupted () {return ISinterrupted (false);} booleano nativo privado isinterrupted (boolean claro);Se puede ver que ambos confían en el interno interno (booleano), lo que devolverá si el hilo se interrumpe y borrará la bandera de interrupción según sea necesario.
Cuando se bloquea una función de función, la función de la biblioteca Java marca InterruptedException en la firma de la fuente de bloqueo y requiere que Write intente captar para manejar las interrupciones.
Cuando el hilo bloquea, como se mencionó anteriormente, Java verifica la bandera de interrupción, lo borra primero y luego arroja una Excepción InterruptedException.
// java.lang.ObjectPublic El vacío final Wait () lanza interruptedException {Wait (0);} Public Final Native Void Wait (Tiempo de tiempo largo) lanza InterruptedException;Si un hilo recibe una Cuercenta InterruptedEx y luego ejecuta el código que lanzará un bloqueo, continuará bloqueando como "No importa". ¡Porque Java borra la bandera de interrupción internamente!
A menudo escribimos los siguientes tres tipos de código que manejan InterruptedException:
Maneje la concepción de interrupción a la capa superior para su procesamiento.
public void foo () lanza interruptedException {SynChronized (Lock) {Lock.Wait (); }}InterruptedException Restablecer el bit de la bandera de interrupción.
intente {sincronizado (bloqueo) {lock.wait (); }} capt (interruptedException e) {thread.currentThread (). interrupt (); //romper; }Termine su trabajo primero y luego vuelva a colocar una EXPERECCIÓN INTERRUPTEDEX.
public void bar () lanza interruptedException {interruptedException ie = null; booleano hecho = falso; while (! ded) {sincronizado (bloqueo) {try {lock.wait (); } capt (interruptedException e) {ie = e; continuar; }} ded = true; } if (es decir! = nulo) {tirar es decir; }}Si un hilo ignora el indicador de interrupción y la concepción de interrupción, todavía funciona bien. Pero esto es contrario a nuestra intención original de diseñar múltiples lecturas. Queremos que los hilos cooperen armoniosamente y de manera ordenada para lograr funciones específicas, por lo que los hilos controlados deben responder a las interrupciones. Y debemos hacer un buen uso de esta libertad dejada por Java a los desarrolladores.
Lo anterior es todo el conocimiento relevante sobre el mecanismo de interrupción de hilo Java que se le presentó esta vez. Si no comprende nada, puede discutirlo en el área de mensajes a continuación. Gracias por su apoyo a Wulin.com.