ScheduledExecutorService para Tarefas Recorrentes
Agende tarefas em intervalos fixos ou com atrasos fixos para sondagens e manutenção em segundo plano.
ScheduledExecutorService para Tarefas Recorrentes é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
Por que usar ScheduledExecutorService?
ScheduledExecutorService estende ExecutorService para oferecer suporte ao agendamento de tarefas. Ele substitui as classes legadas Timer/TimerTask por um agendador baseado em pool de threads e seguro contra exceções.
import java.util.concurrent.*;
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// One-shot delay
scheduler.schedule(
() -> System.out.println("Runs once after 3 seconds"),
3, TimeUnit.SECONDS
);
// Don't forget to shut down eventually:
// scheduler.shutdown();schedule: atraso de execução única
schedule(task, delay, unit) executa a tarefa uma vez após o atraso especificado. Funciona tanto com executável quanto com chamável:
ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
// Runnable:
ScheduledFuture<?> sf1 = s.schedule(
() -> System.out.println("Runnable fired!"), 2, TimeUnit.SECONDS);
// Callable:
ScheduledFuture<Integer> sf2 = s.schedule(
() -> { System.out.println("Callable fired!"); return 42; },
2, TimeUnit.SECONDS);
System.out.println(sf2.get()); // 42 (after 2 seconds)scheduleAtFixedRate
scheduleAtFixedRate(task, initialDelay, period, unit) executa a tarefa repetidamente em uma taxa fixa. Se uma tarefa demorar mais que o período, a próxima execução começa imediatamente depois que ela termina, sem sobreposição.
ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
AtomicInteger count = new AtomicInteger();
ScheduledFuture<?> sf = s.scheduleAtFixedRate(
() -> System.out.println("Tick " + count.incrementAndGet()),
0, // initial delay
1, // period
TimeUnit.SECONDS
);
Thread.sleep(5000);
sf.cancel(false); // stop after 5 ticks
s.shutdown();scheduleWithFixedDelay
scheduleWithFixedDelay(task, initialDelay, delay, unit) espera o atraso especificado DEPOIS que cada tarefa termina antes de iniciar a próxima. É uma boa opção para consultas periódicas cuja duração varia.
s.scheduleWithFixedDelay(
() -> {
System.out.println("Polling... " + Instant.now());
// variable-length polling task
},
0, // no initial delay
5, // 5-second gap AFTER each completion
TimeUnit.SECONDS
);
// Next execution = task end + 5 seconds (not task start)Taxa fixa versus atraso fixo
Distinção principal:
- scheduleAtFixedRate: próximo início = último início + período, com temporização sem deriva
- scheduleWithFixedDelay: próximo início = último término + atraso, com intervalo garantido entre as execuções
Use fixedRate para sinais de atividade e fixedDelay para consultas periódicas cuja duração varia.
ScheduledFuture: cancelamento
schedule/scheduleAtFixedRate/scheduleWithFixedDelay retornam um ScheduledFuture. Chame cancel(false) para interromper as execuções futuras sem interromper a que está em andamento:
ScheduledFuture<?> sf = scheduler.scheduleAtFixedRate(
() -> System.out.println("Heartbeat"), 0, 1, TimeUnit.SECONDS);
// Cancel after 5 seconds
scheduler.schedule(() -> sf.cancel(false), 5, TimeUnit.SECONDS);Tratamento de exceções em tarefas agendadas
Se uma tarefa agendada lançar uma exceção não capturada, o agendador interromperá silenciosamente as execuções recorrentes; não haverá mais execuções. Sempre envolva o código em try-catch:
scheduler.scheduleAtFixedRate(() -> {
try {
// risky work
if (Math.random() < 0.3) throw new RuntimeException("transient");
System.out.println("Success");
} catch (Exception e) {
System.err.println("Task error: " + e.getMessage());
// task continues to run on next interval
}
}, 0, 2, TimeUnit.SECONDS);Prática: atualização do cache
Use uma tarefa agendada para atualizar um cache periodicamente:
class PriceCache {
private volatile Map<String, Double> prices = new HashMap<>();
PriceCache(ScheduledExecutorService scheduler) {
scheduler.scheduleAtFixedRate(this::refresh, 0, 30, TimeUnit.SECONDS);
}
private void refresh() {
System.out.println("Refreshing prices...");
// prices = fetchFromDatabase();
}
Double getPrice(String symbol) { return prices.get(symbol); }
}Prática: novas tentativas com espera progressiva
Implemente novas tentativas com recuo exponencial usando tarefas agendadas:
void retryWithBackoff(Runnable task, int maxRetries, ScheduledExecutorService s) {
AtomicInteger attempts = new AtomicInteger(0);
long[] delay = {1}; // seconds
Runnable wrapper = new Runnable() {
public void run() {
try {
task.run();
} catch (Exception e) {
int n = attempts.incrementAndGet();
if (n < maxRetries) {
delay[0] *= 2;
s.schedule(this, delay[0], TimeUnit.SECONDS);
} else System.err.println("Max retries reached");
}
}
};
s.execute(wrapper);
}Monitoramento: getDelay e getQueue
Inspecione o estado do agendador:
ScheduledFuture<?> sf = scheduler.schedule(() -> {}, 10, TimeUnit.SECONDS);
System.out.println("Delay remaining: " + sf.getDelay(TimeUnit.SECONDS) + "s");
// ThreadPoolExecutor provides queue inspection:
if (scheduler instanceof ScheduledThreadPoolExecutor ste) {
System.out.println("Queue size: " + ste.getQueue().size());
}Encerramento e esvaziamento
Durante o encerramento, decida se as tarefas agendadas ainda devem ser executadas:
ScheduledThreadPoolExecutor ste = (ScheduledThreadPoolExecutor)
Executors.newScheduledThreadPool(2);
// Cancel scheduled tasks on shutdown (default: false = they run)
ste.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
ste.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
ste.shutdown();Verificação rápida
Uma tarefa agendada com scheduleAtFixedRate(..., 1, TimeUnit.SECONDS) leva 3 segundos para ser concluída. Como o agendador lida com isso?
Recapitulação: ScheduledExecutorService
Principais conclusões:
- schedule() — execução única com atraso
- scheduleAtFixedRate() — temporização sem desvio (do início ao início)
- scheduleWithFixedDelay() — intervalo garantido (do fim ao início)
- Exceções não capturadas interrompem silenciosamente as tarefas recorrentes — envolva-as sempre em try-catch
- Cancele com ScheduledFuture.cancel(false)
Perguntas Frequentes
A aula “ScheduledExecutorService para Tarefas Recorrentes” é grátis?
Sim — o texto completo de “ScheduledExecutorService para Tarefas Recorrentes” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “ScheduledExecutorService para Tarefas Recorrentes”?
Agende tarefas em intervalos fixos ou com atrasos fixos para sondagens e manutenção em segundo plano. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “ScheduledExecutorService para Tarefas Recorrentes”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- ExecutorService e Tipos de Pools de Threads
- Envio de Tarefas: Runnable versus Callable
- Future e Tratamento de Erros
- ScheduledExecutorService para Tarefas Recorrentes