Eu gostaria que uma determinada thread, a que roda a main, executasse a intrução interrupt().
Quando eu crio threads manualmente, com Thread thread1 = new Thread(objeto runnable) , eu consigo fazer diretamente thread1.interrupt().
Mas eu estou usando um gerenciador automático de threads.
Quando se usa Executors, esqueça um pouco o conceito de threads.
Em vez disso, veja como é que vocë pode despachar algo a ser executado e que pode ser cancelado.
No seu caso, pense em Tasks, que vocë pode cancelar. (O cancelamento é implementado normalmente com uma InterruptedException, mas isso é um detalhe de implementação )
[quote=entanglement]Quando se usa Executors, esqueça um pouco o conceito de threads.
Em vez disso, veja como é que vocë pode despachar algo a ser executado e que pode ser cancelado.
No seu caso, pense em Tasks, que vocë pode cancelar. (O cancelamento é implementado normalmente com uma InterruptedException, mas isso é um detalhe de implementação )
Eu tenho uma dúvida com relação ao método interrupt(). Se uma thread está em algum dos estados espera, espera sincronizada ou bloqueado, com o método interrupt() nessa thread ela vai para o estado executável (pronto), correto? E se a thread estiver executando? Com a chamada desse método, para qual estado ela vai?
O método interrupt força a execução assíncrona de uma exceção do tipo InterruptedException.
Acontece que a verificação dessa exceção não ocorre em qualquer parte do código, mas sim apenas quando o código está em uma parte em que chama alguma rotina do sistema operacional.
Por exemplo, se sua thread estiver em loop executando apenas código que não chama o sistema operacional (por exemplo, efetuando algum cálculo matemático), a exceção não será verificada e a thread continuará rodando.
Se o método estiver sendo executado e chamar alguma rotina do sistema operacional que verifique a interrupção, a exceção será verificada e lançada.
Portanto, você pode ter comportamentos um pouco diferentes no Windows e no Unix.
No Unix, por exemplo, qualquer operação de disco pode ser interrompida; no caso do Windows, algumas operações de disco não podem ser interrompidas (tipicamente quando usando java.nio). Na prática, no caso do Windows, garantimos apenas que as operações Object.wait, Thread.sleep etc. (as que estão listadas no javadoc de Thread.interrupt: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#interrupt() ) consigam ser interrompidas com sucesso.
Você pode ter, por exemplo, código que consiga copiar arquivos e parar com sucesso no caso do Linux mas não no caso do Windows.
[quote=entanglement]O método interrupt força a execução assíncrona de uma exceção do tipo InterruptedException.
Acontece que a verificação dessa exceção não ocorre em qualquer parte do código, mas sim apenas quando o código está em uma parte em que chama alguma rotina do sistema operacional.
Por exemplo, se sua thread estiver em loop executando apenas código que não chama o sistema operacional (por exemplo, efetuando algum cálculo matemático), a exceção não será verificada e a thread continuará rodando.
Se o método estiver sendo executado e chamar alguma rotina do sistema operacional que verifique a interrupção, a exceção será verificada e lançada.
Portanto, você pode ter comportamentos um pouco diferentes no Windows e no Unix.
No Unix, por exemplo, qualquer operação de disco pode ser interrompida; no caso do Windows, algumas operações de disco não podem ser interrompidas (tipicamente quando usando java.nio). Na prática, no caso do Windows, garantimos apenas que as operações Object.wait, Thread.sleep etc. (as que estão listadas no javadoc de Thread.interrupt: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#interrupt() ) consigam ser interrompidas com sucesso.
Você pode ter, por exemplo, código que consiga copiar arquivos e parar com sucesso no caso do Linux mas não no caso do Windows. [/quote]
Mas para que estado a thread vai se ela estiver no estado “executável” e ocorrer uma instrução interrupt() nela?
Pelo que sei, a instrução interrupt() interrompe a ação corrente da thread. Ela simplesmente vai para o estado “terminado”, como se tivesse terminado a sua tarefa, vai para o estado de espera…?
Suponha que a thread esteja pronta para ser schedulada (ou seja, está em wait, sleep, yield etc. ), ou seja, está parada porque o sistema operacional está executando alguma outra coisa, ou está simplesmente parado.
Nesse caso, o Thread.interrupt irá realmente, quando a thread for schedulada, receber a exceção InterruptedException.
Suponha agora que a thread esteja rodando um loop muito comprido que só faz contas (por exemplo, esteja calculando os números primos de 1 até 100 milhões.) Nesse caso, Thread.interrupt só irá setar uma flag em uma estrutura de dados que a thread tem (e que pode ser consultado usando-se o método “isInterrupted()”. Se a thread que está rodando o loop não fica chamando esse método, não irá parar até que o loop acabe. Note que o fato de a thread gastar 100 segundos (e nesse meio tempo o sistema operacional tenha chaveado a thread entre processadores 1000 x 100 = 100.000 vezes) não quer dizer que a interrupção irá forçar a exceção nessa thread antes do loop terminar.
Você não leu as entrelinhas (para ler a documentação corretamente, você precisa ser um pouco “advogado”. Embora esteja escrito:
Na verdade, se a Thread estiver em um loop comprido, só fazendo contas (e não chamando nenhuma operação de I/O que pode ser interrompida, ou usando Thread.sleep ou etc.), vai ser: