Otro tipo de grupo de tareas es el grupo de tareas programadas. A juzgar por el nombre, podemos suponer que usamos este tipo para programar cuándo se debe iniciar una tarea en particular.

Este tipo de servicio es útil cuando tenemos una tarea para lanzar una actividad después de que haya transcurrido un tiempo o queremos programar una tarea recurrente.

Para usar uno, llamamos a Executors.newScheduledThreadPool(1) .

Hablaremos de los parámetros un poco más tarde. Pero por ahora, lo que necesitamos saber es que cuando se llama a este método, obtenemos un objeto ScheduledExecutorService .

ScheduledExecutorService es una interfaz que amplía ExecutorService .

Los siguientes métodos aparecen en esta interfaz:

Método Explicación

ScheduledFuture<?>
schedule(Runnable command,
                                  long delay, TimeUnit unit);
Crea y ejecuta una acción única que se ejecuta después del retraso especificado.

<V> ScheduledFuture<V>
schedule(Callable<V> callable,
                                      long delay, TimeUnit unit);
Crea y ejecuta un ScheduledFuture objeto que se ejecuta después de un retraso especificado.

ScheduledFuture<?>
scheduleAtFixedRate(Runnable command,
                                             long initialDelay,
                                             long period,
                                             TimeUnit unit);
Crea y ejecuta una acción recurrente que se ejecuta primero después del retraso inicial especificado y luego nuevamente después del período especificado. En otras palabras, la ejecución comenzará después de initialDelay , luego initialDelay + period , luego initialDelay + 2 * period , y así sucesivamente.

ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                long initialDelay,
                                                long delay,
                                                TimeUnit unit);
Crea y ejecuta una acción recurrente que se ejecuta primero después del retraso inicial especificado y luego nuevamente con el retraso especificado entre la finalización de una ejecución y el comienzo de la siguiente.

Entonces, la interfaz nos permite ejecutar tareas a intervalos regulares o después de cierto retraso.

Más información sobre el método newScheduledThreadPool.

Podemos llamarlo de varias formas:


newScheduledThreadPool(int corePoolSize)
corePoolSize es la cantidad de subprocesos que se mantendrán en el grupo, incluso si están inactivos.

newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)

corePoolSize es la cantidad de subprocesos que se mantendrán en el grupo, incluso si están inactivos.

threadFactory es la fábrica que se utiliza al crear nuevos subprocesos.

Ambos métodos crearán un grupo de subprocesos que puede programar acciones para ejecutarse después de un retraso específico o periódicamente.

Veamos un ejemplo para ver cómo funciona ScheduledThreadPool .

Por ejemplo, supongamos que tenemos una tarea para consultar el correo electrónico cada 5 segundos, pero esta verificación no debe afectar al programa principal y conlleva el consumo potencial de recursos adicionales.

Tenemos una clase de tarea que simula revisar el correo electrónico.


public class Task implements Runnable {
   @Override
   public void run() {
       System.out.println("Checking email...");
   }
}

A continuación, creamos un grupo de subprocesos y programamos la verificación.


ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
executorService.scheduleAtFixedRate(new Task(), 0, 5, TimeUnit.SECONDS);

En la salida, cada 5 segundos vemos:

Comprobando correo electrónico...

En general, podemos usar un grupo de este tipo para realizar tareas periódicas de "limpieza", como en el ejemplo. Las tareas de limpieza son tareas que deben realizarse independientemente de lo que esté haciendo el programa principal.