HOWTO · Java
Cómo retrasar unos segundos en Java
Aprende cuándo usar Thread.sleep() para una pausa bloqueante y cuándo programar trabajo retrasado o repetitivo en Java.
En esta página
Para una pausa sencilla, llama a Thread.sleep(): suspende el hilo actual durante el tiempo indicado. Si quieres que una tarea se ejecute más tarde o se repita mientras el hilo que la solicita sigue disponible, usa un ScheduledExecutorService. Los ejemplos muestran ambas opciones, cómo gestionar las interrupciones y cómo limpiar las tareas programadas.
Pausar la ejecución pertenece al grupo de utilidades del Tutorial de Java, con el resto de recetas cotidianas de fechas, números aleatorios y consola.
Usar Thread.sleep() para una pausa bloqueante sencilla
Thread.sleep() acepta una duración en milisegundos y pausa el hilo que lo invoca. Este programa independiente espera un segundo antes de imprimir su mensaje. El método main declara InterruptedException, por lo que la interrupción se propaga al llamador en lugar de descartarse silenciosamente.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(1000);
System.out.println("One second has passed.");
}
}
En un método que no pueda propagar InterruptedException al llamador, captura la excepción y restaura el estado de interrupción con Thread.currentThread().interrupt(). Así, el código de nivel superior puede detectar la solicitud de cancelación y responder según la política de la aplicación. Una espera solo pausa el hilo actual; no pausa los demás hilos del proceso.
Usar TimeUnit.sleep() para indicar la unidad de tiempo
TimeUnit.SECONDS.sleep(2) expresa directamente una pausa de dos segundos. También bloquea el hilo que lo invoca y puede interrumpirse, así que aplica la misma política de interrupciones que con 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.");
}
}
}
Elige esta forma cuando indicar la unidad haga que la duración sea más fácil de entender. TimeUnit.sleep() permite expresar una espera temporizada de forma legible, pero no mantiene disponible el hilo actual para otras tareas mientras transcurre la pausa.
Programar una tarea repetitiva con ScheduledExecutorService
Un ScheduledExecutorService ejecuta un Runnable después de una demora o a intervalos regulares, mientras el hilo que lo invoca sigue disponible. scheduleAtFixedRate() recibe la tarea, una demora inicial, un período y un TimeUnit. El ejecutor invoca el método run() de la tarea; run() contiene el trabajo y no se programa a sí mismo.
Este programa inicia una tarea después de un segundo y solicita que vuelva a ejecutarse cada segundo. Otra acción programada cancela la tarea repetitiva y cierra el ejecutor después de cinco segundos. La programación depende de la disponibilidad durante la ejecución, por lo que pueden variar tanto el número como el momento de las líneas impresas.
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);
}
}
Conserva el ScheduledFuture devuelto si puede que necesites cancelar la tarea repetitiva. Cierra el ejecutor cuando la aplicación ya no lo necesite; de lo contrario, su hilo de trabajo puede mantener el proceso en ejecución. Para una sola acción diferida, usa schedule() en lugar de una programación repetitiva.
Usar una referencia a método con ScheduledExecutorService
Si un método existente sin argumentos representa la tarea, puedes proporcionarlo como Runnable mediante una referencia a método. Este programa programa una llamada para dentro de dos segundos y luego cierra el ejecutor. El cierre impide que se envíen tareas nuevas, pero permite que termine la tarea que ya estaba en cola.
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");
}
}
Usa un método de espera para una pausa breve cuando quieras detener el hilo actual. Elige un ejecutor programado si deben continuar otras tareas o si una tarea debe ejecutarse más tarde o repetirse. La espera bloquea el hilo que la invoca y no requiere limpiar ningún ejecutor; el trabajo programado deja disponible ese hilo, pero debes cerrar el ejecutor y cancelar las tareas repetitivas cuando ya no las necesites.