HOWTO · Java
Comment retarder de quelques secondes en Java
Découvrez quand utiliser Thread.sleep() pour une pause bloquante et quand planifier un travail différé ou répété en Java.
Sur cette page
Pour une simple pause, appelez Thread.sleep() : cette méthode suspend le thread courant pendant la durée demandée. Si une tâche doit s’exécuter plus tard ou se répéter pendant que le thread appelant reste disponible, utilisez un ScheduledExecutorService. Les exemples ci-dessous présentent ces deux options, la gestion des interruptions et le nettoyage des tâches planifiées.
La mise en pause de l’exécution appartient au groupe des utilitaires du Tutoriel Java, avec les autres recettes quotidiennes sur les dates, l’aléatoire et la console.
Utiliser Thread.sleep() pour une pause bloquante simple
Thread.sleep() accepte une durée en millisecondes et met en pause le thread qui l’appelle. Ce programme autonome attend une seconde avant d’afficher son message. Sa méthode main déclare InterruptedException : l’interruption est donc transmise à l’appelant au lieu d’être ignorée.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(1000);
System.out.println("One second has passed.");
}
}
Dans une méthode qui ne peut pas transmettre InterruptedException à son appelant, interceptez l’exception et rétablissez le statut d’interruption avec Thread.currentThread().interrupt(). Le code de niveau supérieur peut alors détecter la demande d’annulation et y répondre selon la politique de l’application. Une mise en veille ne met en pause que le thread courant ; elle n’interrompt pas les autres threads du processus.
Utiliser TimeUnit.sleep() pour préciser l’unité du délai
TimeUnit.SECONDS.sleep(2) exprime directement une pause de deux secondes. Cette méthode bloque toujours le thread appelant et peut être interrompue : appliquez donc la même politique de gestion des interruptions qu’avec Thread.sleep().
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("Two seconds have passed.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Pause interrupted.");
}
}
}
Choisissez cette forme lorsque la précision de l’unité rend la durée plus facile à comprendre. TimeUnit.sleep() est une manière lisible d’exprimer une attente chronométrée ; elle ne permet pas de laisser le thread courant disponible pour d’autres tâches pendant le délai.
Planifier une tâche répétée avec ScheduledExecutorService
Un ScheduledExecutorService exécute un Runnable après un délai ou à intervalles réguliers, tout en laissant le thread appelant disponible. scheduleAtFixedRate() reçoit la tâche, le délai initial, la période et une TimeUnit. L’exécuteur appelle la méthode run() de la tâche ; cette méthode contient le travail à effectuer et ne planifie pas elle-même de nouvelle exécution.
Ce programme démarre une tâche après une seconde et demande une nouvelle exécution chaque seconde. Une autre action planifiée annule la tâche répétée et arrête l’exécuteur après cinq secondes. La planification dépend des ressources disponibles à l’exécution : le nombre de lignes affichées et leur cadence peuvent donc varier.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> task = executor.scheduleAtFixedRate(
() -> System.out.println("Task running"), 1, 1, TimeUnit.SECONDS);
executor.schedule(() -> {
task.cancel(false);
executor.shutdown();
}, 5, TimeUnit.SECONDS);
}
}
Conservez le ScheduledFuture renvoyé si la tâche répétée peut devoir être annulée. Arrêtez l’exécuteur lorsque l’application n’en a plus besoin ; sinon, son thread de travail peut empêcher le processus de se terminer. Pour une seule action différée, utilisez schedule() plutôt qu’une planification répétée.
Utiliser une référence de méthode avec ScheduledExecutorService
Lorsqu’une méthode existante sans argument représente la tâche à effectuer, une référence de méthode permet de la fournir comme Runnable. Ce programme planifie un appel deux secondes plus tard, puis arrête l’exécuteur. L’arrêt empêche la soumission de nouvelles tâches tout en laissant la tâche déjà mise en file d’attente se terminer.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.schedule(Main::executeTask, 2, TimeUnit.SECONDS);
executor.shutdown();
}
private static void executeTask() {
System.out.println("Task running");
}
}
Utilisez une méthode de mise en veille pour une courte pause lorsque vous souhaitez arrêter le thread courant. Choisissez un exécuteur planifié si d’autres tâches doivent pouvoir continuer, ou si une tâche doit s’exécuter plus tard ou se répéter. La mise en veille bloque le thread appelant et ne nécessite aucun nettoyage d’exécuteur ; la planification le laisse disponible, mais l’exécuteur doit être arrêté et les tâches répétées annulées lorsqu’elles ne sont plus nécessaires.