Hoy voy hablar sobre la clase "
ExecutorService", con esta clase no permite gestionar un pool de hilos. A continuación pongo un ejemplo de uso de la clase con comentarios de cada uno de los ejemplos.
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
private ExecutorService executor;
/**
*Clase para terminar todos los hilos
*/
private void endExecutor(){
executor.shutdown();
try
{
if (!executor.awaitTermination(60, TimeUnit.SECONDS))
{
executor.shutdownNow();
if (!executor.awaitTermination(60, TimeUnit.SECONDS))
{
System.err.println("executor no ha terminado");
}
}
} catch (InterruptedException ie) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
/**
* Crea un pool que va a ir creando threads conforme se vayan necesitando
* si hay threads libres, se ponen las tareas a procesarse dentro de dichos threads, y
* las tareas faltantes se procesan en threads nuevos
*/
public void newCachedThreadRool(){
this.executor = Executors.newCachedThreadPool();
for(int i=0; i < 5; i++){
this.executor.execute(new Handler("Hilo_"+i));
}
endExecutor();
}
/**
* crea un pool con el número de threads indicado; dichos threads siempre estarán listos
* para procesar tareas. El pool maneja también una cola de tareas; cada thread toma una
* tarea de la cola y la procesa, y al terminar toma otra tarea de la cola para procesarla, etc en un ciclo
*/
public void newFixedThreadPool(){
this.executor = Executors.newFixedThreadPool(3);
for(int i=0; i < 5; i++){
this.executor.execute(new Handler("Hilo_"+i));
}
endExecutor();
}
/**
* crea un pool de un solo thread, con una cola en donde se ponen las tareas a procesar;
* el thread toma una tarea de la cola, la procesa y toma la siguiente, en un ciclo.
*/
public void newSingleThreadExecutor(){
this.executor = Executors.newSingleThreadExecutor();
for(int i=0; i < 5; i++){
this.executor.execute(new Handler("Hilo_"+i));
}
endExecutor();
}
/**
* crea un pool que va a ejecutar tareas programadas cada cierto tiempo, ya sea una sola
* vez o de manera repetitiva. Es parecido a un timer, pero con la diferencia de que puede
* tener varios threads que irán realizando las tareas programadas conforme se desocupen.
* También hay una versión de un solo thread.
*/
public void newScheduledThreadPool(){
this.executor = Executors.newScheduledThreadPool(3);
for(int i=0; i < 5; i++){
this.executor.execute(new Handler("Hilo_"+i));
}
endExecutor();
}
/**
* Si queremos que despues de la excución nos devuelva algo tenemos que implemetar la
* interfaz Callabe
*/
public void callableThread() throws ExecutionException, InterruptedException{
this.executor = Executors.newCachedThreadPool();
Collection callableResults = new HashSet();
for(int i=0; i < 3; i++){
callableResults.add(new CallableResult("Callable_"+i));
}
//solo uno
Future future = executor.submit((CallableResult)callableResults.toArray()[0]);
//devuelve el resultado de una tare completa correcamente
String result = executor.invokeAny(callableResults);
//Espera a que se termine todos los hilos
List<"Future"> futures = executor.invokeAll(callableResults);
System.out.println("future.get() = " + future.get());
System.out.println("Result invoke any = " + result);
for(int i=0; i < futures.size(); i++){
System.out.println("Result invoke all = " + futures.get(i).get());
}
}
public static void main(String[] args) {
try
{
System.out.println("El numero de procesadores : "+Runtime.getRuntime().availableProcessors());
new Main().callableThread();
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
Cuando copies el código teneies que citar la comillas doble Future porque no me daba un error el editor de html.
A continuación la clase Handler
import java.util.Random;
public class Handler implements Runnable {
private String nombreHilo;
private Random generador;
private int dormir;
public Handler(String name) {
this.nombreHilo = name;
this.generador = new Random();
this.dormir = generador.nextInt(5000);
}
public void run() {
try
{
System.out.println("\t Voy a dormir "+this.dormir+" : "+nombreHilo);
Thread.sleep(this.dormir);
}
catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.println("\t Ya he terminado de dormir : "+nombreHilo);
}
}
public static void main(String[] args) {
try
{
System.out.println("El numero de procesadores : "+Runtime.getRuntime().availableProcessors());
new Main().callableThread();
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
Y por ultimo la clase CallableResult
import java.util.Random;
import java.util.concurrent.Callable;
public class CallableResult implements Callable{
private String nombreHilo;
private Random generador;
private int dormir;
public CallableResult(String name) {
this.nombreHilo = name;
this.generador = new Random();
this.dormir = generador.nextInt(5000);
}
public String call() throws Exception {
try
{
System.out.println("\t Voy a dormir "+this.dormir+" : "+nombreHilo);
Thread.sleep(this.dormir);
System.out.println("\t Ya he terminado de dormir : "+nombreHilo);
return "terminado "+nombreHilo;
}
catch (InterruptedException exception) {
return exception.getMessage();
}
}
}
Con esto es todo sobre la clase ExecutorService