Ejecutor, ExecutorService, Ejecutor - 1

"¡Hola, amigo!"

"Nada es perfecto cuando se crea por primera vez. Lo mismo ocurre con los subprocesos. Con el tiempo, los creadores de Java se convencieron de las deficiencias de la interfaz Runnable. No admitía el lanzamiento de excepciones y no permitía descubrir el resultado de ejecutar tareas…”

"La interfaz Runnable es más adecuada para grandes tareas independientes que para pequeñas subtareas que desea ejecutar una docena a la vez y luego recopilar sus resultados".

"Es por eso que se inventó la interfaz Callable . Es mucho más adecuada para la ejecución paralela de tareas pequeñas que Runnable y Thread, en parte porque es una interfaz genérica".

"Aquí hay una implementación típica de la interfaz:"

Ejemplo
class ReverseString implements Callable<String>
{
 String str;

 ReverseString(String str)
 {
  this.str = str;
 }

 public String call() throws Exception
 {
  StringBuilder builder = new StringBuilder(str);
  builder.reverse();
  return builder.toString();
 }
}

"A diferencia de Runnable , aquí necesitamos anular el método de llamada, que devuelve un resultado del tipo especificado por el argumento de tipo. Este enfoque es mucho más conveniente que el método de ejecución de la interfaz de Runnable, que devuelve vacío. A veces, los desarrolladores tenían que idear varias soluciones para obtener el resultado de un hilo".

"Veo."

"Y ahora mire cómo Callable puede funcionar junto con ThreadPoolExecutor:

"Primero, el método de envío de la clase ThreadPoolExecutor devuelve un objeto Future parametrizado. Puede usar este objeto para averiguar si una tarea ha finalizado y obtener el resultado".

"Así es como funciona:"

Ejemplo
// 1. Create a ThreadPoolExecutor
ExecutorService service = Executors.newFixedThreadPool(5);

// 2. Add a task to it
Future<String> task = service.submit(new ReverseString("Amigo"));

// 3. Wait until the task is done
while(!task.isDone())
{
 Thread.sleep(1);
}

// 4. Try to get the result
//We will get either the result, or an exception if one occurred while the task was being executed
try
{
 System.out.println("Full string : " + task.get());
}
catch (Exception ie)
{
 ie.printStackTrace(System.err);
}
  
// 5. Stop the ThreadPool.
service.shutdown();

"¡Muy lejos! Me gusta especialmente la clase Futuro. ¿Qué métodos tiene?"

"Aquí están los más interesantes:"

Método Descripción
boolean cancel(boolean mayInterrupt);
Detiene la tarea.
boolean isCancelled();
Devuelve verdadero si la tarea se detuvo.
boolean isDone();
Devuelve verdadero si la tarea ha terminado de ejecutarse.
V get() throws InterruptedException, ExecutionException;
Devuelve el resultado del método de llamada o genera una excepción si se produce.

"¡Genial! Entonces también puedes detener tareas".

"No confíe demasiado en esto, no todos los subprocesos pueden detenerse. Pero si una tarea todavía está en la cola, funcionará bien".

"Me gusta este enfoque. Es mucho más conveniente que crear hilos usted mismo y luego tratar de obtener un resultado de ellos".

"Genial. Ahí es donde terminaremos hoy".