4

Uso de hilos en Java(parte 3)

Anteriormente hemos visto:

  • Ejecución secuencial.
  • Uso de concurrencia heredando de la clase Thread e implementar la interfaz Runnable.
  • Particionamiento del trabajo entre los hilos.
  • Comparación del tiempo de la ejecución secuencial vs la ejecución paralela.

Ahora veremos:

  • Ejecutores : Explicación, tipos, ventajas y desventajas.
  • Ejemplo de uso de ejecutores.

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:

  • Los ejecutores de un solo hilos : Single Thread Executor.
  • Los ejecutores de un tamaño(N) fijo : Fixed Thread Pool.
  • Los ejecutores de tamaño variable : Cached Thread Pool, este cambia su tamaño en función de las tareas que va recibiendo.
  • Los ejecutores altamente configurables : Thread Pool Executor, con este ejecutor podemos definir varias características.

Ventajas:

  1. La reutilización de hilos evita la necesidad de crear más hilos, esto resulta muy beneficioso ya este es un proceso altamente costoso además de la memoria que emplea cada hilo, con esto obtenemos un grado de mejoría(dependiente del programa y sus requisitos).
  2. Los ejecutores se encargán de la gestión del procesamiento de las tareas(creación de hilos, el uso de start y join).
    Desventajas:
  3. No resultan necesarios cuando nuestro número de hilos creados se ajusta al número de núcleos de nuestra máquina, en este caso un ejecutor sería más dañino que beneficioso.

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:
salidaEjemplo.png

Escribe tu comentario
+ 2