1. Introdução
Este artigo registra alguns pontos de conhecimento sobre o mecanismo de interrupção no Java Multithreading. Consiste principalmente na diferença entre o método de parada, os métodos interrompidos () e o ISInterrupted () e executa análises simples a partir da implementação do código -fonte.
Existem 3 maneiras de encerrar os threads em execução em java
①O thread sai normalmente, ou seja, o método run () foi executado
② Use o método STOP () na classe Thread para encerrar com força o thread. No entanto, o método STOP () expirou e não é recomendado para usá -lo
③Use Mecanismo de interrupção
Não há nada a fazer quando o thread sai normalmente. O mecanismo de interrupção é introduzido em detalhes abaixo. Vamos primeiro analisar o código -fonte do método STOP (). A chave são os comentários no código -fonte. Explica por que STOP () não é seguro, qual tópico é interrompido no método Stop ()?
/*** força o thread a parar de executar. Isso pode resultar em uma* <Code> SecurityException </code> sendo elevada (no thread atual). <Code> SecurityException </code> (no thread atual).* <p>* O encadeamento representado por este thread é forçado a parar o que quer que esteja fazendo anormalmente e para jogar um recém -criado* <Code> ThreadDeath </code> se o aplicativo não pode ser iniciado. <Code> ThreadDeath </code> A menos que ele deva fazer alguma operação extraordinária* de limpeza (observe que o lançamento de* <code> threadDeath </code> Causa <Code> Finalmente </code> Clauses de* <code> tente </code> As instruções a serem executadas antes do thread* morrem oficialmente). Se uma cláusula <code> Catch </code> captura um objeto A* <Code> ThreadDeath </code>, é importante redobrar o objeto* para que o thread realmente morra. Não é possível* modificar este thread. Interromper um thread com* Thread.stop faz com que ele desbloqueie todos os monitores que ele* bloqueou (como uma conseqüência natural da exceção* <code> threadDeath </code> não controlada). Se* algum dos objetos previamente protegidos por esses monitores estava em um estado inconsistente, os objetos danificados se tornam visíveis para* outros threads, potencialmente resultando em comportamento arbitrário. Muitos* usos de <code> stop </code> devem ser substituídos pelo código que simplesmente* modificam alguma variável para indicar que o thread de destino deve* parar de funcionar. O thread de destino deve verificar essa variável* regularmente e retornar de seu método de execução de maneira ordenada* se a variável indicar que é parar de funcionar. Se o thread de destino aguarda por longos períodos (em uma variável de condição,* por exemplo), o método <code> interrompe </code> deve ser usado para* interromper a espera. Depreciado?
Como comentado acima, as linhas 9 a 16 indicam que o método Stop () pode parar "outros threads". O thread que executa o método Thread.stop () é chamado de encadeamento atual, enquanto o "outro thread" é o thread representado pelo encadeamento do objeto que chama o método Thread.stop ().
como:
public static void main (string [] args) {mythread thread = novo mythread ... // .... thread.stop (); // ..}No método principal, o encadeamento atual é o encadeamento principal. Ele é executado na linha 4 e deseja interromper o thread "outro thread". Este outro thread é o thread representado pelo objeto Thread da nova classe Mythread.
As linhas 21 a 23 indicam que um fio que ainda não foi iniciado pode ser interrompido. Seu efeito é: quando o encadeamento começa, termina imediatamente.
Os comentários após a linha 48 mostram profundamente por que o método STOP () está descontinuado! Por que é inseguro.
Por exemplo, o Threada Thread possui monitores responsáveis por proteger certos recursos críticos, como a quantidade de transferências bancárias. Quando o processo de transferência está em andamento, o encadeamento principal chama o método Threada.stop (). Como resultado, o monitor é liberado e os recursos que protege (a quantidade de transferência) provavelmente serão inconsistentes. Por exemplo, a conta A diminuiu em 100, enquanto a conta B não aumentou em 100.
Segundo, mecanismo de interrupção
Existem muitos detalhes sobre como usar o mecanismo de interrupção corretamente em Java. Os métodos interrompidos () e ISInterrupted () refletem se o encadeamento atual está em um estado interrompido.
① Interrompido ()
/*** testa se o encadeamento atual foi interrompido. O status* <i> interrompido </i> do thread é limpo por esse método. Em outras palavras, se esse método fosse chamado duas vezes em sucessão, a* segunda chamada retornaria falsa (a menos que o fio atual fosse* interrompido novamente, depois que a primeira chamada tivesse limpado seu status interrompido* e antes que a segunda chamada o tivesse examinada). foi interrompido;* <code> false </code> caso contrário.
A partir dos comentários no código -fonte, ele testa o estado de interrupção do encadeamento atual e esse método limpará o estado de interrupção.
②Isinterrupted ()
/*** testa se este tópico foi interrompido. O status <i> interrompido* </i> do thread não é afetado por esse método. isInterrupted () {return isInterrupted (false);}Como pode ser visto nos comentários do código -fonte, o método ISInterrupted () não limpará o estado de interrupção.
③Fiference entre o método interrupto () e o método ISInterrupted ()
Como pode ser visto no código -fonte, ambos os métodos são chamados de Isinterrupted (Boolean ClearInterrupted), exceto que um com o parâmetro é verdadeiro e o outro com o parâmetro é falso.
/*** Testes se algum thread foi interrompido. O estado interrompido* é redefinido ou não baseado no valor do ClearInterrupted que é passado.
Portanto, a primeira diferença é que um limpa o sinalizador de interrupção e o outro não limpa o bit de sinalizador de interrupção.
Depois de analisar o código -fonte, você pode ver a segunda diferença na declaração de retorno:
public static boolean interromped () {return currentThread (). Isinterrupted (true);}/**************************/public boolean isInterrupted () {return isInterrupted (false);}interrompido () testa o estado interrompido do thread atual. O isInterrupted () testa o encadeamento representado pelo objeto que chama o método. Um é um método estático (testa o estado de interrupção do encadeamento atual) e o outro é um método de instância (testa o estado de interrupção do thread representado pelo objeto de instância).
A seguir, é apresentado um exemplo específico para esclarecer ainda mais essa diferença.
Há uma classe de thread personalizada da seguinte maneira:
classe pública mythread estende thread {@OverridePublic void run () {super.run (); para (int i =; i <; i ++) {System.out.println ("i =" + (i +);}}}Vamos primeiro olhar para o exemplo do método interrupto ():
classe pública Run {public static void main (string [] args) {try {mythread thread = new Mythread (); thread.start (); thread.sleep (); thread.interrupt (); // thread.currentThread (). // ...A linha 5 inicia o encadeamento e a linha 6 faz com que o fio principal durma por 1 segundo, para que o encadeamento tenha a chance de obter a execução da CPU.
Depois que o thread principal dorme para 1s, ele retoma a execução da linha 7 e solicita que interrompa o encadeamento.
A linha 9 testa se o encadeamento está em um estado interrompido. Qual tópico está sendo testado aqui? ? ? A resposta é o tópico principal. porque:
(1) Interrupted () testa o status de interrupção do encadeamento atual
(2) O encadeamento principal executa a instrução da 9ª linha, então o encadeamento principal é o fio atual
Vejamos o exemplo do método ISInterrupted ():
public
Na linha 8, o método ISInterrupted () chamado pelo objeto Thread. Portanto, o estado de interrupção do encadeamento representado pelo objeto Thread é testado. Desde a linha 7, o encadeamento principal solicita interromper o thread, o resultado na linha 8 é: true