"¡Hola, amigo!

"Todo lo nuevo es solo algo viejo que hemos olvidado. Hoy hablaré sobre detener hilos. Espero que ya hayas olvidado cómo funciona el método interrupt()".

"Sí, Ellie, lo he olvidado por completo".

"Genial. Entonces te lo recordaré".

"En Java, si alguien quiere detener un subproceso en ejecución, puede señalar esto al subproceso. Para hacer esto, debe establecer la variable isInterrupted oculta del objeto Thread en verdadero".

"Cada subproceso tiene un método de interrupción (), que se utiliza para establecer este indicador. Cuando se llama al método de interrupción (), la variable isInterrupted dentro del objeto Thread se establece en verdadero".

"Y cuando se llama al método Thread.sleep() o join() en un hilo, el método verifica si el indicador isInterrupted está establecido para el hilo actual. Si este indicador está establecido (la variable isInterrupted es igual a verdadero), entonces los métodos lanzar una excepción interrumpida ".

"Aquí, te recordaré un viejo ejemplo:"

Código Descripción
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
El método de ejecución de Clock obtiene el objeto Thread para el hilo actual.

La clase Clock escribe la palabra "Tick" en la consola una vez por segundo siempre que la variable isInterrupt del subproceso actual sea falsa.

Cuando isInterrupt se vuelve verdadero, el método de ejecución finaliza.

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clockThread.interrupt();
}
El subproceso principal inicia un subproceso secundario (reloj) que debe ejecutarse para siempre.

Espere 10 segundos y cancele la tarea llamando al método de interrupción.

El hilo principal termina su trabajo.

El hilo del reloj termina su trabajo.

"Aquí usamos el método de suspensión como parte de un ciclo infinito en el método de ejecución . En el ciclo, la variable isInterrupt se verifica automáticamente. Si un subproceso llama al método de suspensión , el método primero verifica si isInterrupt es verdadero para ese subproceso (la uno que llamó al método de suspensión). Si es verdadero, entonces el método no dormirá. En su lugar, lanza una excepción interrumpida ".

"Pero en este ejemplo, verificamos constantemente la variable isInterrupted en la condición del bucle".

"Recuerdo que hubo algunas razones por las que no pudimos usar este enfoque. ¿Podrías recordármelo?"

" Primero , el método de ejecución no siempre tiene un bucle. El método podría consistir simplemente en unas pocas docenas de llamadas a otros métodos. En este caso, tendría que agregar una verificación isInterrupted antes de cada llamada al método".

" En segundo lugar , algunos métodos que implican muchas acciones diferentes pueden tardar mucho tiempo en ejecutarse".

" Tercero , lanzar una excepción no reemplaza la verificación isInterrupted. Es solo una adición conveniente. La excepción lanzada le permite deshacer rápidamente la pila de llamadas al método de ejecución en sí".

Cuarto , el método de suspensión se usa mucho. Resulta que este útil método se ve mejorado por una verificación implícita que no es menos útil. Es  como si nadie hubiera agregado específicamente la verificación, pero ahí está.  Esto es muy valioso cuando está usando el código de otra persona y no puede agregar el cheque usted mismo".

" En quinto lugar , la verificación adicional no degrada el rendimiento. Llamar al método de suspensión significa que el subproceso no debería hacer nada (excepto dormir), por lo que el trabajo adicional no molesta a nadie".

"Eso es exactamente lo que dijiste anteriormente".

"¿Y qué hay de su declaración, " Nadie puede garantizar que un hilo se detendrá. Solo un hilo puede detenerse a sí mismo ". ¿Puede explicar eso?"

"Seguro."

"Anteriormente, en las primeras versiones de Java, los subprocesos tenían un método stop(). Y cuando lo llamaba, la JVM en realidad detenía el subproceso. Pero si un subproceso estaba haciendo algo fuera de la JVM (por ejemplo, escribir en un archivo o llamar OS funciones) cuando se interrumpió de esta manera, la interrupción causó muchos problemas, como archivos no cerrados, recursos del sistema no liberados, etc.

"Una reunión general de creadores de Java decidió eliminar el método para forzar la detención de subprocesos. Ahora todo lo que podemos hacer es establecer un indicador determinado (isInterrupted) y esperar que el código del subproceso se haya escrito correctamente, de modo que este indicador se procese. Este indicador es como un letrero que dice: 'Hilo, deténgase, por favor. ¡Es muy importante!'. Pero si se detiene o no, es asunto suyo".

"Pero, ¿qué pasa con la InterruptedException?"

"¿Qué pasa si el código que se ejecuta en este subproceso tiene un montón de bloques try-catch? Incluso si ocurre una InterruptedException en algún lugar, definitivamente no hay garantía de que algún try-catch no lo atrape y se olvide de él. Por lo tanto, no hay garantías de que el hilo se detendrá".

"Otra cosa es que los subprocesos ya se consideran programación de muy bajo nivel. Pero les contaré sobre eso la próxima vez".

"¡Tú no eres Ellie, eres Scherezade!"

"¡Entonces, Amigo! ¿Está todo claro en la lección actual?"

"Sí."

"Bueno, bien."