Anteriormente hemos visto:
Ahora veremos:
Ejecutores : Son un tipo de datos que viene implementado por Java y tiene como objetivo la reutilización de los hilos, anteriormente nosotros hemos creado hilos para procesar una tarea, esto se debe a que las clases que empleamos implementan la interfaz Runnable(la cual indica que los objetos que la implementan tiene que ser tratados como tareas) o heredan de la clase Thread(esta clase implementa Runnable, es por ello que hay que implementar el método run), Java pensó que sería conveniente que un hilo procesará una tarea y cuando la terminase continuará procesando más tareas, con ello no tendríamos que crear un hilo por tarea sino que reutilizaríamos ese hilo, los ejecutores estan basados en ese propósito => gestionar las tareas que nosotros les pasamos como argumentos para que ellos se encarguen de su gestión.
Java provee 4 tipos de ejecutores:
Ventajas:
Veamos ahora un ejemplo de uso, en esta ocasión veremos un ejecutor que gestiona varias tareas que tienen como objetivos calcular el factorial de un número dado:
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Ejecutores {
static double suma = 0.0;// Con este método creamos un número N de tareas.
public static Runnable[] obtenerTareas() {
System.out.println("Indique el número de tareas a realizar");
Scanner entrada = new Scanner(System.in);int numeroTareas = Integer.parseInt(entrada.nextLine());
entrada.close();
Runnable[] resultado = new Runnable[numeroTareas];for (int i = 0; i < numeroTareas; ++i) {
resultado[i] = new Runnable() {
@Override
public void run() {
// En esta sección implementamos la lógica de las tareas, yo usaré un println.double aleatorio = Math.random() * System.nanoTime();System.out.println("Esta tarea ha obtenido " + aleatorio + " como número aleatorio");
suma += aleatorio;
}
};
}
return resultado;
}
public static void main(String[] args) {
Runnable[] tareas = obtenerTareas();// Vamos a crear un ejecutor de tamaó fijo acorde al número de núcleos lógicos// de mi máquina:int numeroNucleos = Runtime.getRuntime().availableProcessors();
ExecutorService ejecutor = Executors.newFixedThreadPool(numeroNucleos);for (int i = 0; i < tareas.length; ++i) {
ejecutor.execute(tareas[i]);
}
// Tras terminar el envio de tareas, se le indica al ejecutor que ya no reciba// más tareas e implementamos una espera a la finalización de sus tareas.
ejecutor.shutdown(); // No recibir más tareas.while (!ejecutor.isTerminated()) { // Con este bucle denotamos la espera.
}
System.out.println("Se terminaron las tareas, la suma de todos los número aleatorios ha sido = " + suma);
}
}
Ejecución: