0Pricing
Java Academy · Aula

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

  1. ExecutorService e Tipos de Pools de Threads
  2. Envio de Tarefas: Runnable versus Callable
  3. Future e Tratamento de Erros
  4. ScheduledExecutorService para Tarefas Recorrentes
← Voltar para Java Academy