ScheduledExecutorService para tareas recurrentes
Programe tareas con frecuencias o retrasos fijos para realizar sondeos y tareas de mantenimiento en segundo plano.
ScheduledExecutorService para tareas recurrentes es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.
¿Por qué usar ScheduledExecutorService?
ScheduledExecutorService amplía ExecutorService para admitir la programación de tareas. Sustituye las clases heredadas Timer/TimerTask por un programador respaldado por un grupo de hilos y seguro frente a excepciones.
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: retraso de una sola ejecución
schedule(task, delay, unit) ejecuta la tarea una vez después del retraso especificado. Funciona tanto con Runnable como con Callable:
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) ejecuta la tarea repetidamente a una frecuencia fija. Si una tarea tarda más que el periodo, la siguiente ejecución comienza inmediatamente después de que termine la anterior, sin solaparse.
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 el retraso especificado DESPUÉS de que termine cada tarea antes de iniciar la siguiente. Es adecuado para sondeos en los que la duración de la tarea varía.
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)Frecuencia fija frente a retraso fijo
Diferencia principal:
- scheduleAtFixedRate: siguiente inicio = último inicio + periodo (temporización sin desviación)
- scheduleWithFixedDelay: siguiente inicio = última finalización + retraso (intervalo garantizado entre ejecuciones)
Use fixedRate para señales de latido y fixedDelay para sondeos en los que la duración de la tarea varía.
ScheduledFuture: cancelación
schedule/scheduleAtFixedRate/scheduleWithFixedDelay devuelven un ScheduledFuture. Llame a cancel(false) para detener las ejecuciones futuras sin interrumpir la que está en curso:
ScheduledFuture<?> sf = scheduler.scheduleAtFixedRate(
() -> System.out.println("Heartbeat"), 0, 1, TimeUnit.SECONDS);
// Cancel after 5 seconds
scheduler.schedule(() -> sf.cancel(false), 5, TimeUnit.SECONDS);Gestión de excepciones en tareas programadas
Si una tarea programada lanza una excepción no capturada, el programador detiene silenciosamente las ejecuciones recurrentes: no se producen más ejecuciones. Envuélvala siempre en un bloque 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áctica: actualización de la caché
Use una tarea programada para actualizar una caché periódicamente:
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áctica: reintentos con backoff
Implemente reintentos con retroceso exponencial mediante tareas programadas:
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);
}Supervisión: getDelay y getQueue
Inspeccione el estado del planificador:
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());
}Apagado y vaciado
Al apagar el sistema, decida si las tareas programadas deben seguir ejecutándose:
ScheduledThreadPoolExecutor ste = (ScheduledThreadPoolExecutor)
Executors.newScheduledThreadPool(2);
// Cancel scheduled tasks on shutdown (default: false = they run)
ste.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
ste.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
ste.shutdown();Comprobación rápida
Una tarea programada con scheduleAtFixedRate(..., 1, TimeUnit.SECONDS) tarda 3 segundos en completarse. ¿Cómo gestiona esto el planificador?
Resumen: ScheduledExecutorService
Conceptos clave:
- schedule() — ejecución única con retraso
- scheduleAtFixedRate() — temporización sin deriva (de inicio a inicio)
- scheduleWithFixedDelay() — intervalo garantizado (del final al inicio)
- Las excepciones no capturadas detienen silenciosamente las tareas recurrentes — envuélvalas siempre en un bloque try-catch
- Cancele con ScheduledFuture.cancel(false)
Preguntas frecuentes
¿La lección «ScheduledExecutorService para tareas recurrentes» es gratis?
Sí — el texto completo de «ScheduledExecutorService para tareas recurrentes» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.
¿Qué aprenderé en «ScheduledExecutorService para tareas recurrentes»?
Programe tareas con frecuencias o retrasos fijos para realizar sondeos y tareas de mantenimiento en segundo plano. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Java Academy?
No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «ScheduledExecutorService para tareas recurrentes»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Java Academy?
Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- ExecutorService y tipos de grupos de hilos
- Envío de tareas: Runnable frente a Callable
- Future y gestión de errores
- ScheduledExecutorService para tareas recurrentes