Los ejecutores encapsulan pools de hilos reutilizables y una cola de tareas. Permiten controlar el paralelismo sin crear y destruir hilos a mano, reduciendo latencias y fuga de recursos.
Executors.newFixedThreadPool(n): tamaño fijo; bueno para CPU-bound cuando n ≈ núcleos.Executors.newCachedThreadPool(): crece bajo demanda, reutiliza hilos inactivos; útil para I/O-bound variable.Executors.newSingleThreadExecutor(): un solo hilo, garantiza orden de ejecución.Executors.newScheduledThreadPool(n): agenda tareas periódicas o con retraso.ExecutorServicesubmit(Runnable): ejecuta sin retorno.submit(Callable): ejecuta devolviendo un Future con el valor.invokeAll(): lanza una colección de Callable y espera todos los resultados.invokeAny(): devuelve el resultado del primer Callable exitoso y cancela el resto.import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
public class DemoExecutor {
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(2);
Callable<String> t1 = () -> {
TimeUnit.MILLISECONDS.sleep(300);
return "Tarea 1";
};
Callable<String> t2 = () -> {
TimeUnit.MILLISECONDS.sleep(100);
return "Tarea 2";
};
List<Future<String>> resultados = pool.invokeAll(Arrays.asList(t1, t2));
for (Future<String> f : resultados) {
System.out.println(f.get());
}
String primero = pool.invokeAny(Arrays.asList(t1, t2));
System.out.println("Primero en terminar: " + primero);
pool.shutdown();
}
}
ExecutorServiceshutdown(): deja de aceptar nuevas tareas y espera que terminen las pendientes.shutdownNow(): intenta interrumpir hilos y devuelve tareas no iniciadas.awaitTermination(): bloquea hasta que el pool termina o vence un timeout.