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))?

public static void main(String[] args) {

        Thread ma = Thread.currentThread();
        MinhaThread mt = new MinhaThread("mi");

        try {
            mt.start();
            synchronized (ma) {
                ma.wait(1000l);
            }
            
        } catch (InterruptedException e) {
            log("Passou os 10s.");
        } catch (Exception e) {
            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]

3 Respostas

sergiotaborda

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

class TimedExecutor implements Executor{

   public void execute(Runnable r ){
          TimerThread  tt = new TimerThread (r , 2000); // 2 segundos
          tt.start();
   }

}
class TimerThread extends Thread {

  int timerOut; // milesegundos
  Runnabble  runnable 

  public void run (){
         Timer  timer = new Timer(true);
          timer.schedule(new TimedTimerTask(), timerOut);
          runnable.run(); // corre codigo que faz algo
          timer.cancel();
  }

  private class TimedTimerTask{
       public void run(){
             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
package br;

public class GerenciadorThread {

    public void executa(Thread aExecutar, long tempoEmMs) throws Exception {
        aExecutar.start();
        Thread.sleep(tempoEmMs);
        if (aExecutar.isAlive()) {
            aExecutar.stop();            
            throw new Exception("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...)

public static void main(String[] args) {
        GerenciadorThread gt = new GerenciadorThread();
        Thread aExecutar = new Thread(new Tarefa());

        try {
            gt.executa(aExecutar, 9000l);
        } catch (Exception e) {
            System.err.println(e);
        }
    }
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;
            throw new Exception("A thread excedeu o tempo limite.");
        }
Criado 12 de maio de 2008
Ultima resposta 12 de mai. de 2008
Respostas 3
Participantes 2