Neste artigo, falaremos sobre o mecanismo de interrupção de interrupção do thread java.
Tópico de interrupção
O método Thread.Interrupt () do thread é interromper o thread. Ele definirá o bit de status de interrupção do thread, ou seja, definido como true. Se o encadeamento interrompido morre, aguarda uma nova tarefa ou continua a correr para a próxima etapa, depende do próprio programa. O thread detectará esse sinalizador de interrupção de tempos em tempos para determinar se o thread deve ser interrompido (se o sinalizador de interrupção é verdadeiro). Ele não interrompe um segmento em execução como o método de parada.
Determine se o tópico é interrompido
Para determinar se um thread enviou uma solicitação de interrupção, use o thread.currentThread (). IsInterrupted () Método (porque não limpará o sinalizador de interrupção bit imediatamente após a definição do sinalizador de interrupção do thread como verdadeiro, ou seja, ele não definirá o sinalizador de interrupção como falso). Em vez disso, não use o método Thread.Interrupted () (o bit de sinalizador de interrupção será limpo após o método ser chamado, ou seja, redefinir para false), o método para julgar. A seguir, é apresentado o método de interrupção do fio quando está em um loop:
while (! thread.currentThread (). IsInterrupted () && mais trabalho a fazer) {faça mais trabalho}Sinalizador de status de interrupção
Existem os seguintes métodos no mecanismo de interrupção de interrupção:
Portanto, o mecanismo de interrupção de interrupção não interrompe o encadeamento atual, mas uma alteração na marcação de interrupção. Vamos testá -lo com exemplos primeiro.
classe pública interrupttest {// O tempo consumido aqui é usado para imprimir estática privada longa tempo = 0; private estático void reastime () {time = system.currenttimemillis (); } private estático void PrintContent (String Content) {System.out.println (Content + "Time:" + (System.currenttimemillis () - time)); } public static void main (string [] args) {test1 (); } private estático void test1 () {Thread1 Thread1 = new Thread1 (); Thread1.start (); // interromper a interrupção após 3 segundos de atraso, tente {thread.sleep (3000); } catch (interruptedException e) {e.printStackTrace (); } Thread1.Interrup (); printContent ("interrupção de execução"); } classe estática privada Thread1 estende o thread {@Override public void run () {resettime (); int num = 0; while (true) {if (isInterrupted ()) {printContent ("Thread atual é interruptado"); quebrar; } num ++; if (num % 100 == 0) {printContent ("num:" + num); }}}}}}}O código acima é iniciar um thread1 Thread e adicionar continuamente 1 a NUM no loop while do encadeamento1 e imprimi -lo uma vez a cada múltiplo de 100 (impeça que a impressão seja muito rápida). Então, depois de dormir por 3000 milissegundos, o encadeamento principal chama o método de interrupção do thread1 Thread. Então vamos olhar para a saída:
interromper a interrupção
Pode -se observar que, depois de tomar cerca de 3000 milissegundos, isto é, depois que o encadeamento principal dorme, o Thread1 Thread para e o Thread1 Thread para porque o método IS -ISiSi -TEMPO no while loop retorna true, então o intervalo sai o loop while. Ou seja, o papel da interrupção e é interrompido aqui é equivalente ao papel do SETXX e GETXX, mantendo uma variável booleana.
Manipulação de exceções de interrupção
Obviamente, o mecanismo de interrupção não é apenas uma mudança e detecção de bits de status de interrupção, mas também pode lidar com exceções de interrupção. Sabemos que o método Thread.sleep () precisa pegar a exceção de interrupção, então vamos adicionar um atraso no sono e experimentar
while (true) {if (isInterrupted ()) {printContent ("Thread atual é interruptado"); quebrar; } num ++; // Sleep Try {Thread.sleep (1); } catch (interruptedException e) {e.printStackTrace (); } if (num % 100 == 0) {printContent ("num:" + num); }}Vejamos o resultado da saída:
interromper a interrupção
Aqui, descobriremos que depois de dormir, o valor de NUM de saída é significativamente menor (os NUMs atingem 1 bilhão quando não estão dormindo, e parece que a CPU executa operações simples muito rapidamente). Haha, mas esse não é o ponto. O ponto é que, após a exceção de saída, a saída ISiSi -ISiSTRATA FALSA, e o Thread1 Thread continua sendo executado e não sai do loop while. Então, por que isso? Acabamos de adicionar um sono.
Se houver uma operação no thread1 Thread que precisar capturar a exceção interrompedException, como o sono de Thread, o método de união, a espera do objeto, a condição aguarda etc., força a exceção interrompedException para capturar, quando o thread1. O método de interrupção for chamado, ele lançará uma exceção interrompida da Thread1. Então, no while loop, essa exceção pode ser capturada e, depois que essa exceção for lançada, o sinalizador de interrupção do thread será redefinido para false imediatamente. Portanto, quando for interrompido na próxima vez em que o loop estiver determinado a ser falso, não quebrará e, em seguida, o loop enquanto continuará sendo executado.
Portanto, o método interromp () executará diferentes operações com base no fato de haver código no método de execução no encadeamento que deve capturar a interrupção da UrruptException:
Cenários de aplicação de interrupção
Normalmente, a interrupção é adequada para julgamentos de marca de loop na execução de threads, por exemplo
while (! isInterrupted ()) {...} No entanto, se houver um bloqueio nesse loop, o encadeamento não poderá julgar a próxima tag ISiSi -ISiRUPT e, mesmo que o método interromp () seja chamado, ele não poderá sair do loop e o thread não poderá sair. Por exemplo
enquanto (! isInterrupted ()) {... while (true) {// O tópico está preso aqui, o mecanismo interrompido não pode ser respondido a}}Dessa forma, a interrupção será impotente e o tópico continuará sendo executado e não será interrompido e interrompido.
Exemplos de teste para ver meu github-Javatest
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.