O mecanismo de interrupção do encadeamento fornece um método para acordar um encadeamento de uma espera de bloqueio, tentando interromper o fluxo de processamento existente do thread de destino e respondendo a novos comandos. Java deixa essa liberdade para os desenvolvedores, e devemos fazer bom uso.
Hoje falaremos sobre o mecanismo de interrupção dos threads java.
O mecanismo de interrupção do thread fornece um método que possui dois usos comuns:
Acorde o thread do bloqueio de espera e faça o processamento correspondente de "interrupção controlada".
Tente informar o tópico de destino: interrompa o fluxo de processamento existente e responda a novos comandos.
Tome o primeiro objetivo como exemplo, consulte o seguinte código:
sincronizado (bloqueio) {tente {while (! check ()) {Lock.wait (1000); }} catch (interruptEdException e) {e.printStackTrace (); }}Este código usa o mecanismo de espera/notificação fornecido pelo Java. A execução do thread do bloqueio.wait () bloqueará. Existem três situações para restaurar o thread para ser executado.
1. Timeout 1000ms termina e o próximo código é executado normalmente.
2. Outro tópico executa o seguinte código para acordar ativamente
sincronizado (bloqueio) {Lock.NotifyAll (); // ou Lock.Notify ();}Isso também executará o próximo código normalmente.
3. Outro tópico necessário para esperar é "interromper"
// Obtenha a referência ao thread de espera A; A.Interrup ();
O thread A que é "interrompido" lançará uma exceção interruptedException no Lock.wait ().
Para resumir, você pode pensar que objeto.wait () está fazendo estas coisas internamente:
boolean checkTimeout = timeout> 0; thread Current = Thread.currentThread (); Lock.addwaiter (atual); while (! current.isnotified ()) {if ( lançar new interruptedException (); } if (checkTimeout) {if (timeout == 0) quebra; tempo esgotado--; }}Isso não é completamente preciso, porque a espera não usa esse método de "pesquisa ocupada" para verificar, mas a lógica de julgar os bits de bandeira está correta.
Vamos começar com a operação "emitir manualmente interromper" mencionada acima
// interface Sun.nio.ch.InterruptiblePublic Interruptible {void interromp (Thread var1);} // java.lang.threadprivate bloqueador interruptível volátil; bloqueador final de objetos privado; sincronizado (bloqueador) {interruptível b = bloqueador; if (b! = null) {interrupt0 (); B. interrupção (isto); retornar; }} interrupt0 ();} // apenas para definir o flagPrivate interrupto nativo void interrupt0 ();Pode -se ver que Thread.Interrupt () primeiro junta as permissões e, na verdade, chama interrupt0 () para definir o sinalizador de interrupção do thread. Se o thread atual tiver o NIO's Interruptível, ele também ligará de volta.
Observe que interrupt0 () apenas define o sinalizador de interrupção do thread.
O que acontece quando um thread não está bloqueando e não está em áreas que não são controladas pela lógica do programa Java, como object.wait (), thread.join (), thread.sleep ()? A resposta é que nada acontecerá e se o thread é interrompido só pode ser conhecido verificando ativamente o sinalizador de interrupção.
Como verificar? O thread expõe duas interfaces, thread.interrupted () e thread.isinterrupted ().
// java.lang.threadpublic estático boolean interromped () {return currentThread (). Isinterrupted (true);} public boolean iSinterrupted () {return é interruptado (false);} private nativo privado boolean isinterrupted (boolean nivelado);Pode -se observar que ambos dependem da interrupção interna (booleana), que retornará se o thread é interrompido e limpar o sinalizador de interrupção, conforme necessário.
Quando uma função chama bloqueia, a função da biblioteca Java Marks lança interruptedException na assinatura da fonte de bloqueio e requer a pegada de gravação para lidar com interrupções.
Quando o thread bloqueia, como mencionado acima, o Java verifica o sinalizador de interrupção, limpa -o primeiro e depois joga uma interrupção de exceção.
// java.lang.ObjectPublic Final Void Wait () lança interruptedException {wait (0);} public final nativo nativo void wait (longo tempo limite) lança interruptedException;Se um thread receber uma interrupção e executar o código que lançará um bloqueio, ele continuará bloqueando como "não importa". Porque Java limpa a bandeira de interrupção internamente!
Costumamos escrever os três tipos de código a seguir que lidam com a InterruptedException:
Lidar com a interrupção da Upper Cayer para processamento.
public void foo () lança interruptedException {sincronizado (bloqueio) {Lock.wait (); }}InterruptedException Redefina o bit de sinalizador de interrupção.
tente {sincronizado (Lock) {Lock.wait (); }} catch (interruptEdException e) {thread.currentThread (). interrupt (); //quebrar; }Termine seu trabalho primeiro e depois jogue uma interrupção novamente.
public void bar () lança interruptedException {interruptedException ie = null; boolean done = false; while (! feito) {sincronizado (bloqueio) {try {Lock.wait (); } catch (interruptedException e) {ie = e; continuar; }} done = true; } if (ie! = null) {tiro ie; }}Se um thread ignorar o sinalizador de interrupção e interromper aception, ele ainda funcionará bem. Mas isso é contrário à nossa intenção original de projetar multithreading. Queremos que os threads cooperem harmoniosamente e de maneira ordenada para obter funções específicas, para que os threads controlados respondam às interrupções. E devemos fazer bom uso dessa liberdade deixada por Java para os desenvolvedores.
O exposto acima é todo o conhecimento relevante sobre o mecanismo de interrupção do thread java apresentado a você desta vez. Se você não entende nada, pode discutir isso na área de mensagens abaixo. Obrigado pelo seu apoio ao wulin.com.