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(); CollectionCuando 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 HandlercallableResults = 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()); } } }
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
Hola amigo, oye me gustaría saber si te puedo hacer una pregunta... y tmb saber en cuanto tiempo puedo tener respuesta de esta... Saludos
ResponderEliminarDispara, ¿Dime cual es tú duda?
ResponderEliminarComo haría para eliminar un solo hilo del pool despues de cierto tiempo, no lo eliminar el pool por completo sino un hilo
ResponderEliminarSaludos
Hola wmercado
ResponderEliminarPara poder para un hilo después de cierto tiempo porque esta tardando demasiado o es un bucle infinito. lo que pues hacer es llamar al método cancel de la interfaz de Future Api:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html#cancel%28boolean%29
Aqui te dejo un pequeño ejemplo
ExecutorService executor = Executors.newSingleThreadExecutor();
Future task = executor.submit(new Task());
String str;
try {
str = task.get(5, TimeUnit.SECONDS);
} finally {
task.cancel(true);
}
Espero que esto resuelva tú duda
Saludos
Este comentario ha sido eliminado por el autor.
ResponderEliminarmuchas gracias xabe, me sirvio mucho el ejemplo, ahora tengo un problema y es que al implementar esto los hilos en cierto modo ya no son concurrentes viéndolo en el log tienen un comportamiento secuencial, ya que todos los hilo tiene que pasar el método task.get(5, TimeUnit.SECONDS) y valida el tiempo de cada task y hasta que termine ese hilo no se sigue con el otro, que mejora se puede hacer en ese aspecto que no pierda la concurrencia.
ResponderEliminarSaludos
Hola
ResponderEliminarA ver si este ejemplo sirve para solucinar tu problema
http://stackoverflow.com/questions/11915968/java-executorservice-pause-resume-a-specific-thread
Saludos