Ajuda com thread - como implementar uma espera de execução
3 respostas
dreampeppers99
A situação é a seguinte, quero executar uma thread e se em dez segundos ela não fazer o que foi designado a ela eu possa interromper e dar uma mensagem ao usuário... algo mais ou menos o código abaixo.
Qual o jeito pra se fazer isso (inclusive suspendendo a thread (secundária))?
publicstaticvoidmain(String[]args){Threadma=Thread.currentThread();MinhaThreadmt=newMinhaThread("mi");try{mt.start();synchronized(ma){ma.wait(1000l);}}catch(InterruptedExceptione){log("Passou os 10s.");}catch(Exceptione){log(e.toString());log(e.getClass().getName());}}
O Fluxo do que desejo é assim:
[list]1º executo minha aplicação (uma thread)[/list]
[list]2º "lanço" a execução de uma 2º thread[/list]
[list]3º se a 2º thread não acabar o que ela tiver que fazer em 10s, então eu a suspendo assim como também posso lançar uma execeção mais elegante à aplicação.[/list]
Proponho que crie um java.util.concurrent.Executor. Vc configura-o com o tempo de timeout e passa quantos runnables quiser que ele execute.( não precisa trabalhar com thread directamente)
Internamente vc usa um timer associado ao runable. Se o timer activar antes do fim do runable vc desativa-a enviando um Exception. Cuidado que isto pode destruir dados porque é fora do padrão convencionado para threads. Para poder criar este mecanismo vc precisa de um objeto auxiliar que contenha o timer e o runable associado e implemente a logica de controle. Esse objeto provavelmente terá que ser uma thread que possa receber o InterruptException do timer
classTimedExecutorimplementsExecutor{publicvoidexecute(Runnabler){TimerThreadtt=newTimerThread(r,2000);// 2 segundostt.start();}}classTimerThreadextendsThread{inttimerOut;// milesegundosRunnabblerunnablepublicvoidrun(){Timertimer=newTimer(true);timer.schedule(newTimedTimerTask(),timerOut);runnable.run();// corre codigo que faz algotimer.cancel();}privateclassTimedTimerTask{publicvoidrun(){TimerThread.this.interrupt();}}}
Lembre-se que o triger temporal pode acontecer depois de passado o tempo. O timer garante que não será executado antes do tempo, mas não garante que seja executado exactamente depois do tempo terminar.
dreampeppers99
Mas e no caso JDK 1.4.x?
dreampeppers99
packagebr;publicclassGerenciadorThread{publicvoidexecuta(ThreadaExecutar,longtempoEmMs)throwsException{aExecutar.start();Thread.sleep(tempoEmMs);if(aExecutar.isAlive()){aExecutar.stop();thrownewException("A thread excedeu o tempo limite.");}}}
Minha solução caseira (não se há algum problema em usá-la, consequências que meu entendimento em Thread não consegue ver) ... Pode ser usada assim? (nos meus testes, foi tudo bem, errou quando tinha que errar, fez certo quando tinha que fazer...)
Será que existe algum problema nessa abordagem.?
Na linha em que lança a execeção (mesmo que génerica) devo fazer uma atribuição a null (vi isso num site)?
if(aExecutar.isAlive()){
aExecutar.stop(); aExecutar=null;thrownewException("A thread excedeu o tempo limite.");}