"Olá, Amigo!

"Tudo que é novo é apenas algo antigo que esquecemos. Hoje falarei sobre parar threads. Espero que você já tenha esquecido como funciona o método interrupt()."

"Sim, Ellie, eu esqueci completamente."

"Ótimo. Então eu vou lembrá-lo."

"Em Java, se alguém quiser parar um thread em execução, ele pode sinalizar isso para o thread. Para fazer isso, você precisa definir a variável oculta isInterrupted do objeto Thread como true."

"Cada Thread tem um método de interrupção (), que é usado para definir esse sinalizador. Quando o método de interrupção () é chamado, a variável isInterrupted dentro do objeto Thread é definida como verdadeira."

"E quando o método Thread.sleep() ou join() é chamado em um thread, o método verifica se o sinalizador isInterrupted está definido para o thread atual. Se esse sinalizador estiver definido (a variável isInterrupted é igual a true), então os métodos lance uma InterruptedException ."

"Aqui, vou lembrá-lo de um exemplo antigo:"

Código Descrição
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
O método run do Clock obtém o objeto Thread para o thread atual.

A classe Clock grava a palavra "Tick" no console uma vez por segundo, desde que a variável isInterrupt do thread atual seja falsa.

Quando isInterrupt se torna verdadeiro, o método run termina.

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

Thread.sleep(10000);
clockThread.interrupt();
}
O thread principal inicia um thread filho (relógio) que deve ser executado para sempre.

Aguarde 10 segundos e cancele a tarefa chamando o método de interrupção.

O thread principal termina seu trabalho.

O thread do relógio termina seu trabalho.

"Aqui usamos o método sleep como parte de um loop infinito no método run . No loop, a variável isInterrupt é verificada automaticamente. Se um thread chama o método sleep , o método primeiro verifica se isInterrupt é verdadeiro para esse thread (o um que chamou o método sleep). Se for verdadeiro, então o método não vai dormir. Em vez disso, ele lança um InterruptedException ."

"Mas, neste exemplo, verificamos constantemente a variável isInterrupted na condição do loop."

"Lembro que havia algumas razões pelas quais não podíamos usar essa abordagem. Você poderia me lembrar?"

" Primeiro , o método run nem sempre tem um loop. O método pode simplesmente consistir em algumas dezenas de chamadas para outros métodos. Nesse caso, você teria que adicionar uma verificação isInterrupted antes de cada chamada de método."

" Em segundo lugar , algum método que envolve muitas ações diferentes pode levar muito tempo para ser executado."

" Terceiro , lançar uma exceção não substitui a verificação isInterrupted. É apenas uma adição conveniente. A exceção lançada permite que você desfaça rapidamente a pilha de chamadas de volta ao próprio método run ."

" Quarto , o método de suspensão é muito usado. Acontece que esse método útil é aprimorado por uma verificação implícita que não é menos útil. É  como se ninguém especificamente tivesse adicionado a verificação, mas aí está.  Isso é super valioso quando você está usando o código de outra pessoa e você não pode adicionar a verificação sozinho."

" Quinto , a verificação adicional não degrada o desempenho. Chamar o método sleep significa que o thread não deve fazer nada (exceto dormir), então o trabalho extra não incomoda ninguém."

"Isso é exatamente o que você disse anteriormente."

"E quanto à sua afirmação, ' Ninguém pode garantir que um thread será interrompido. Somente um thread pode interromper a si mesmo. » Você pode explicar isso?"

"Claro."

"Anteriormente, nas primeiras versões do Java, os encadeamentos tinham um método stop(). E quando você o chamava, a JVM realmente parava o encadeamento. funções do sistema operacional) quando foi interrompido dessa forma, a interrupção causou muitos problemas, como arquivos não fechados, recursos do sistema não liberados, etc."

"Uma reunião geral dos criadores de Java decidiu remover o método para interromper threads à força. Agora tudo o que podemos fazer é definir um determinado sinalizador (isInterrupted) e esperar que o código do thread tenha sido escrito corretamente, para que esse sinalizador seja processado. Este sinalizador é como uma placa que diz: 'Enfie, pare, por favor. É muito importante!'. Mas parar ou não é problema dela."

"Mas e a InterruptedException?"

"E se o código em execução neste encadeamento tiver vários blocos try-catch? Mesmo que um InterruptedException ocorra em algum lugar, definitivamente não há garantia de que algum try-catch não o capturará e o esquecerá. Portanto, não há garantias de que o o fio vai parar."

"Outra coisa é que os threads já são considerados programação de baixo nível. Mas falarei sobre isso na próxima vez."

"Você não é Ellie, você é Scheherazade!"

"Então, amigo! Está tudo claro na lição atual?"

"Sim."

"OK, bom."