0Pricing
Java Academy · Leçon

ScheduledExecutorService pour les tâches récurrentes

Planifiez des tâches à intervalles fixes ou avec des délais fixes pour l’interrogation et la maintenance en arrière-plan.

ScheduledExecutorService pour les tâches récurrentes est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

Pourquoi utiliser ScheduledExecutorService ?

ScheduledExecutorService étend ExecutorService pour prendre en charge la planification des tâches. Il remplace les classes historiques Timer/TimerTask par un ordonnanceur reposant sur un ensemble de fils d’exécution et sûr vis-à-vis des exceptions.

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 : délai à exécution unique

schedule(task, delay, unit) exécute la tâche une seule fois après le délai indiqué. Fonctionne avec une tâche exécutable comme avec une tâche appelable :

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) exécute la tâche de manière répétée à un taux fixe. Si une tâche dure plus longtemps que la période, l’exécution suivante commence immédiatement après sa fin, sans chevauchement.

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) attend le délai indiqué APRÈS la fin de chaque tâche avant de démarrer la suivante. Convient à l’interrogation lorsque la durée des tâches varie.

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)

Taux fixe contre délai fixe

Différence essentielle :

  • scheduleAtFixedRate : prochain démarrage = dernier démarrage + période (temporisation sans dérive)
  • scheduleWithFixedDelay : prochain démarrage = dernière fin + délai (intervalle garanti entre les exécutions)

Utilisez le taux fixe pour les signaux de maintien en vie et le délai fixe pour l’interrogation lorsque la durée des tâches varie.

ScheduledFuture : annulation

schedule/scheduleAtFixedRate/scheduleWithFixedDelay renvoie un ScheduledFuture. Appelez cancel(false) pour arrêter les exécutions futures sans interrompre celle qui est en cours :

ScheduledFuture<?> sf = scheduler.scheduleAtFixedRate(
    () -> System.out.println("Heartbeat"), 0, 1, TimeUnit.SECONDS);

// Cancel after 5 seconds
scheduler.schedule(() -> sf.cancel(false), 5, TimeUnit.SECONDS);

Gestion des exceptions dans les tâches planifiées

Si une tâche planifiée lève une exception non interceptée, l’ordonnanceur arrête silencieusement les exécutions récurrentes : il n’y en a plus aucune. Encapsulez toujours la tâche dans un bloc 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);

Cas pratique : actualisation d’un cache

Utilisez une tâche planifiée pour actualiser périodiquement un cache :

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); }
}

Cas pratique : nouvelle tentative avec temporisation progressive

Implémentez une nouvelle tentative avec temporisation exponentielle au moyen de tâches planifiées :

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);
}

Surveillance : getDelay et getQueue

Inspectez l’état du planificateur :

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());
}

Arrêt et vidage

Lors de l’arrêt, déterminez si les tâches planifiées doivent continuer à s’exécuter :

ScheduledThreadPoolExecutor ste = (ScheduledThreadPoolExecutor)
    Executors.newScheduledThreadPool(2);

// Cancel scheduled tasks on shutdown (default: false = they run)
ste.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
ste.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);

ste.shutdown();

Vérification rapide

Une tâche planifiée avec scheduleAtFixedRate(..., 1, TimeUnit.SECONDS) prend 3 secondes pour s’exécuter. Comment le planificateur gère-t-il cette situation ?

Récapitulatif : ScheduledExecutorService

Points essentiels :

  • schedule() — exécution unique avec délai
  • scheduleAtFixedRate() — temporisation sans dérive (du début au début)
  • scheduleWithFixedDelay() — intervalle garanti (de la fin au début)
  • Les exceptions non interceptées arrêtent silencieusement les tâches récurrentes — entourez-les toujours d’un bloc try-catch
  • Annulez avec ScheduledFuture.cancel(false)

Questions Fréquemment Posées

La leçon « ScheduledExecutorService pour les tâches récurrentes » est-elle gratuite ?

Oui — le texte complet de « ScheduledExecutorService pour les tâches récurrentes » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « ScheduledExecutorService pour les tâches récurrentes » ?

Planifiez des tâches à intervalles fixes ou avec des délais fixes pour l’interrogation et la maintenance en arrière-plan. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « ScheduledExecutorService pour les tâches récurrentes » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. ExecutorService et types de pools de threads
  2. Soumettre des tâches : Runnable et Callable
  3. Future et gestion des erreurs
  4. ScheduledExecutorService pour les tâches récurrentes
← Retour à Java Academy