Agendamento de Tarefas com TimerTask

O agendamento de tarefas permite que se tenha rotinas em nosso sistema que sejam executadas em um determinado dia, horário ou mesmo em pequenos intervalos de tempo. Neste tutorial veremos como usar as bibliotecas TimerTask e Timer, presentes no JDK desde a versão 1.3 do Java.

1. Tipos de Agendamento

  • Periódico: quando uma tarefa é executada diversas vezes em um pequeno ou grande intervalo de tempo.
  • Execução única (one-shot): quando temos uma ação executada uma única vez ao dia ou em um horário pré-definido uma única vez.

2. Classes Envolvidas

  • java.util.TimerTask: irá representar a tarefa a ser agendada. É uma classe abstrata que implementa a interface Runnable, assim, devemos criar uma sub-classe que implemente o método run().
  • java.util.Timer: irá representar o agendado de tarefas através de uma Thread.

3. Implementação

Vamos começar criando uma classe chamada Agendamentos que irá possuir os métodos de agendamento e um método main(). Também teremos uma classe chamada Execucoes que terá o método que será executado pelos agendamentos.

Listagem 1. Classe Agendamentos
package br.mb.tutorialTimerTask;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Agendamentos {

    private static int count = 0;

    public static void main(String[] args) {
        Agendamentos a = new Agendamentos();
        a.primeiraTarefa();
    }

    private void primeiraTarefa() {
        final Timer t = new Timer();
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Counting " + (++count) +
                        " Time: " + new Date()
                );
                new Execucoes().tabuada(count);
                if (count == 5) {
                    t.cancel();
                }
            }

        }, 5000, 3000);
    }
}
Listagem 2. Classe Execucoes
package br.mb.tutorialTimerTask;

public class Execucoes {

    public void tabuada(int valor) {
        for (int i = 1; i < 11; i++) {
            System.out.println(i + " * " + valor + " = " + (i * valor));
        }
    }
}

Na listagem 2, foi criado um método chamado tabuada que recebe como par metro um valor inteiro. Este método quando executado exibe a tabuada do par metro. Na listagem 1, temos um método chamado primeiraTarefa() que é nossa tarefa agendada. Quando este método for executado, após 5 segundos ele irá iniciar a tarefa, ou seja, executar o método tabuada() e após 3 segundos, executará novamente até o contador count for igual a 5. Quando o contador for 5, iremos cancelar a tarefa através do método cancel() da classe Timer.

No método primeiraTarefa() criamos um objeto do tipo Timer e em seguida fazemos uma chamada ao método schedule() deste objeto. Este método recebeu como 1° parametro uma classe anônima da do tipo TimerTask. O 2° parametro representa o tempo em milissegundos que levará para a tarefa ser executada pela primeira vez e o 3° parametro representa o intervalo de tempo entre cada execução da tarefa. Como dito na sessão 2, a classe TimerTask deve implementar o método run(), e é nele que a tarefa a ser executada deve ser informada. Essa foi uma tarefa do tipo periódica.

Na listagem 3, vamos criar um método que será executado em um dia definido no código, assim, teremos uma execução de tarefa do tipo Execução Única. Ajuste a data para o dia em que você está estudando este tutorial, para que a execução ocorra.

Listagem 3. Método segundaTarefa
public class Agendamentos {
    private void segundaTarefa() {
        Calendar data = Calendar.getInstance();
         //2011 - ano
         //4 - mês (janeiro equivale a 0, fevereiro a 1, ..., dezembro a 11)
         //30 - dia
        data.set(2011, 4, 30);

        final Timer t = new Timer();
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Counting " + (++count) +
                        " Time: " + new Date()
                );
                new Execucoes().tabuada(count);
                t.cancel();
            }

        }, data.getTime() );
    }
}

Na listagem 4, vamos criar um método que será executado em um horário pré-definido, assim, teremos uma execução de tarefa do tipo Periódica.

Listagem 4. Método terceiraTarefa
public class Agendamentos {
    private void terceiraTarefa() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, 18);
        c.set(Calendar.MINUTE, 22);
        c.set(Calendar.SECOND, 0);

        Date time = c.getTime();

        final Timer t = new Timer();
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Counting " + (++count) +
                        " Time: " + new Date()
                );
                new Execucoes().tabuada(count);
                t.cancel();
            }

        }, time );
    }
}

A hora definida no exemplo foi 18:22:00. Ajuste a sua vontade, pode colocar um ou dois minutos após a hora marcada no relógio do seu sistema operacional para executar o teste. Para que a tarefa seja executada de forma periódica, ou seja, todos os dias as 18:22:00, o método cancel() da classe Timer não deve ser chamado, como ocorreu no exemplo da listagem 4. Caso ele seja adicionado ao corpo do método, após a tarefa ser executada pela primeira vez, não será mais executada nos dias seguintes já que o método cancel() finaliza a tarefa.

Referências

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...