Uso das classes Timer e TimerTask
Criação de Timers
- Discutimos o uso de objetos que usam threads internamente para fazer seu trabalho
- Exemplo: Timer usado para escalonar tarefas
- Objetos da classe java.util.Timer escalonam instaâncias da classe TimerTask
- Eis um exemplo de um programa que realiza uma tarefa depois de um certo atraso
import java.util.Timer;
import java.util.TimerTask;
/**
* Simple demo that uses java.util.Timer to schedule a task
* to execute once 5 seconds have passed.
*/
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.println("Time's up!");
timer.cancel(); //Terminate the timer thread
}
}
public static void main(String args[]) {
new Reminder(5);
System.out.println("Task scheduled.");
}
}
- Quando você rodar o exemplo, vai ver:
Task scheduled.
(depois de 5 segundos)
Time's up!
- O programa ilustra o uso de um "Timer Thread" para executar uma tarefa
- Implementamos um subclasse de TimerTask e especificamos o que fazer no método run()
- Criamos um thread através da instanciação de Timer
- Está claro para você que deve haver um segundo thread em Timer? O que ocorreria se
usássemos Thread.sleep(5000) diretamente?
- Instanciamos o TimerTask (new RemindTask())
- Escalonamos a execução da tarefa com o método schedule
- O método schedule faz thread.sleep(5000) em outro thread
- Também podemos executar a tarefa num momento específico:
//Get the Date corresponding to 11:01:00 pm today.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 1);
calendar.set(Calendar.SECOND, 0);
Date time = calendar.getTime();
timer = new Timer();
timer.schedule(new RemindTask(), time);
Parando Timer Threads
- Normalmente, um programa executa enquanto os threads estiverem executando
- Há 4 formas de terminar um Timer thread:
- timer.cancel()
- Faça com que o Timer thread seja um "daemon" criando o timer assim: new
Timer(true)
- Um "daemon" é algo que roda como serviço: quando não há mais quem possa
usar o serviço, o próprio serviço pode morrer
- Se apenas threads do tipo daemon estiver no ar, o programa termina
- Após a execução das tarefas do Timer thread, remova todas as referências ao timer
- Chame o método System.exit()
- O programa inteiro, com todos seus threads termina
- O programa acima usa a primeira forma de terminar o thread
- Fazer com que o thread seja um daemon thread não funcionaria (por quê?)
- Às vezes, o programa não consegue terminar por causa de outros threads (além dos
Timer threads)
- Exemplo: se usar AWT, nem que seja para beepar, AWT vai criar um thread (não daemon) e
manter o programa vivo
- O exemplo abaixo precisa de System.exit() para o programa terminar
public class ReminderBeep {
...
public ReminderBeep(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.println("Time's up!");
toolkit.beep();
//timer.cancel(); // Not necessary because
// we call System.exit
System.exit(0); // Stops the AWT thread
// (and everything else)
}
}
...
}
Execução repetida de uma tarefa
- No exemplo abaixo, a tarefa é repetida 1 vez por segundo
public class AnnoyingBeep {
Toolkit toolkit;
Timer timer;
public AnnoyingBeep() {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(),
0, //initial delay
1*1000); //subsequent rate
}
class RemindTask extends TimerTask {
int numWarningBeeps = 3;
public void run() {
if (numWarningBeeps > 0) {
toolkit.beep();
System.out.println("Beep!");
numWarningBeeps--;
} else {
toolkit.beep();
System.out.println("Time's up!");
//timer.cancel(); // Not necessary because
// we call System.exit
System.exit(0); // Stops the AWT thread
// (and everything else)
}
}
}
...
}
Task scheduled.
Beep!
Beep! (one second after the first beep)
Beep! (one second after the second beep)
Time's up! (one second after the third beep)
- Os métodos schedule que podem ser chamados para execução repetida são os seguintes:
schedule(TimerTask task, long delay, long period)
schedule(TimerTask task, Date time, long period)
scheduleAtFixedRate(TimerTask task, long delay, long period)
scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
- Nos métodos acima:
- schedule(...) usam delays fixos e o periodo pode portanto ser maior que o pedido
- scheduleAtFixedRate(...) usam delays variáveis de forma a manter os periodos fixos
Nenhum comentário:
Postar um comentário