[TimerTask] - Quando utiliza-las? [Resolvido]

10 respostas
lina

Oi,

Um programa rodava em Thread. Foi resolvido modificar para TimerTask.

Acontece que nem sempre essas tasks ocorrem no tempo determinado em sua inicialização. Não sei o que acontece, elas simplesmente morrem?!

Quando utiliza-las?

Tchauzin!

10 Respostas

davidbuzatto

Oi lina,

Como a TimerTask está sendo executada?
Vc está usando um Timer?

Pode passar o trecho de código?

[]´s

davidbuzatto

Dois links interessantes:


[]´s

E

lina:
Oi,

Um programa rodava em Thread. Foi resolvido modificar para TimerTask.

Acontece que nem sempre essas tasks ocorrem no tempo determinado em sua inicialização. Não sei o que acontece, elas simplesmente morrem?!

Quando utiliza-las?

Tchauzin!

Para cada java.util.Timer, é criada uma thread que roda todas as TimerTasks associadas com ela. O que pode ocorrer:

a) Se uma TimerTask demorar mais que o devido, atrasa as outras, e
b) Se uma TimerTask morrer com uma exceção não tratada, mata a thread dessa TimerTask e você vai ver que as outras TimerTasks não serão executadas.

O caso b) pode ser resolvido usando um try { … } catch (Throwable thr) { … } para evitar que a exceção escape e mate a thread.

lina
davidbuzatto:
Oi lina,

Como a TimerTask está sendo executada?
Vc está usando um Timer?

Pode passar o trecho de código?

[]´s

Oi,

Estou criando assim:

TaskTimer
TaskTimer	= new Timer(true);

// Registra a task de Teste.
// A classe TesteTask estende a classe TimerTask e implementa o método run().
TaskTimer.schedule(io_tk_TesteTask = new TesteTask(), 5000, 60000);

Tchauzin!

lina

entanglement:
lina:
Oi,

Um programa rodava em Thread. Foi resolvido modificar para TimerTask.

Acontece que nem sempre essas tasks ocorrem no tempo determinado em sua inicialização. Não sei o que acontece, elas simplesmente morrem?!

Quando utiliza-las?

Tchauzin!

Para cada java.util.Timer, é criada uma thread que roda todas as TimerTasks associadas com ela. O que pode ocorrer:

a) Se uma TimerTask demorar mais que o devido, atrasa as outras, e
b) Se uma TimerTask morrer com uma exceção não tratada, mata a thread dessa TimerTask e você vai ver que as outras TimerTasks não serão executadas.

O caso b) pode ser resolvido usando um try { … } catch (Throwable thr) { … } para evitar que a exceção escape e mate a thread.

Oi,

Tanto a situação a) e b) notei isso já em produção (no cliente rs). E para tratar o item b) utilizei um catch(Exception ex) {…} para ela não escapar!

Valeria a pena a criação de uma simples Thread para substituir a task? Lembrando que estamos falando de varias TimerTask…

Tchauzin!

Andre_Brito

Lina,

Eu não gosto muito da Timer. Se você der uma olhada por aí, vai ver que não sou só eu que não acho a Timer muito legal (não é frescura minha não… a TimerTask e a Timer podem ser bem simples, mas elas tem alguns probleminhas). Você pode usar, ao invés, a classe ScheduledExecutorService, que é mais fácil, flexível e você tem mais controle sobre o agendamento (schedule) de tarefas.

Além disso, quando você usa a SES, você não precisa da TimerTask. Como você falou que existia algo que usava Thread (se você implementou do jeito legal, você provavelmente fez ela uma subclasse de Runnable), é só você colocar essa sua Thread na SES.

lina

Andre Brito:
Lina,

Eu não gosto muito da Timer. Se você der uma olhada por aí, vai ver que não sou só eu que não acho a Timer muito legal (não é frescura minha não… a TimerTask e a Timer podem ser bem simples, mas elas tem alguns probleminhas). Você pode usar, ao invés, a classe ScheduledExecutorService, que é mais fácil, flexível e você tem mais controle sobre o agendamento (schedule) de tarefas.

Além disso, quando você usa a SES, você não precisa da TimerTask. Como você falou que existia algo que usava Thread (se você implementou do jeito legal, você provavelmente fez ela uma subclasse de Runnable), é só você colocar essa sua Thread na SES.

Oi,

Obrigada! Vou dar uma olhada no SES…

Tchauzin!

lina

Oi,

Passei a utilizar o ScheduledThreadPoolExecutor.

Desta maneira:
private class TesteThread extends ScheduledThreadPoolExecutor
{
	
   public TesteThread(final int an_thread_number_pool)
   {
      super(an_thread_number_pool);
				
      ScheduledExecutorService
      lo_scd = Executors.newScheduledThreadPool(an_thread_number_pool);
      lo_scd.scheduleAtFixedRate
      (
         new Runnable() {  
            public  void run() {
                    // .....  
            }
         }, 
         5000, 
         60000, 
         TimeUnit.MILLISECONDS

      );
   }
}

O grande problema agora é como parar essa ThreadPoolExecutor.
Estou chamando o método shutdownNow e nada. A mesma marca como Terminated, porém continua executando o Runnable. Vai saber?!

Tchauzin!

E

De modo geral, só é possível encerrar um Callable ou Runnable se ele sair com um InterruptedException, ou se ficar examinando uma flag. Isso é porque shutdown ou shutdownNow faz exatamente isso (lança uma InterruptedException em todas as threads que estão sendo usadas pelo Executor. )

Para isso ocorrer:

a) Ou esse Callable ou Runnable tem algum ponto do código que seja interruptível com um InterruptedException (por exemplo, ler ou gravar de arquivos ou sockets, Thread.sleep, ou algum método de alguma classe de java.util.concurrent que saia com InterruptedException) , ou
b) Você pode checar uma flag. No caso em que o Runnable ou Callable tem acesso a um Future, por exemplo (veja http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html ) é possível checar o valor de isCancelled.

lina

entanglement:
De modo geral, só é possível encerrar um Callable ou Runnable se ele sair com um InterruptedException, ou se ficar examinando uma flag. Isso é porque shutdown ou shutdownNow faz exatamente isso (lança uma InterruptedException em todas as threads que estão sendo usadas pelo Executor. )

Para isso ocorrer:

a) Ou esse Callable ou Runnable tem algum ponto do código que seja interruptível com um InterruptedException (por exemplo, ler ou gravar de arquivos ou sockets, Thread.sleep, ou algum método de alguma classe de java.util.concurrent que saia com InterruptedException) , ou
b) Você pode checar uma flag. No caso em que o Runnable ou Callable tem acesso a um Future, por exemplo (veja http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html ) é possível checar o valor de isCancelled.

Oi,

Pois então… vou fazer assim… no meu teste funcionou!

Obrigada!

Tchauzin!

Criado 25 de novembro de 2010
Ultima resposta 30 de nov. de 2010
Respostas 10
Participantes 4