Requisito previo: Futuro y exigible
Futuro:
Una interfaz Future proporciona métodos para verificar si el cálculo está completo, esperar a que finalice y recuperar los resultados del cálculo . El resultado se recupera utilizando el método get() de Future cuando se completa el cálculo y se bloquea hasta que se completa.
Future y FutureTask están disponibles en el paquete java.util.concurrent de Java 1.5.
Tarea futura:
- Implementación de FutureTask Interfaz Future y RunnableFuture Interface, significa que uno puede usar FutureTask como Runnable y puede enviarse a ExecutorService para su ejecución.
- Cuando uno llama a objetos Future.submit() Callable o Runnable, la mayoría de las veces ExecutorService crea FutureTask, y también se puede crear manualmente.
- FutureTask actúa como un pestillo.
- El cómputo representado por FutureTask se implementa con la interfaz Callable.
- Implementa la interfaz Future o Callable.
- El comportamiento del método get() depende del estado de la tarea. Si las tareas no se completan, el método get() espera o se bloquea hasta que se completa la tarea. Una vez completada la tarea, devuelve el resultado o lanza una ExecutionException.
Un ejemplo de uso de Future es trabajar con grupos de subprocesos . Cuando uno envía una tarea a ExecutorService que lleva mucho tiempo de ejecución, devuelve un objeto Future inmediatamente. Este objeto Future se puede usar para completar tareas y obtener el resultado del cálculo.
Ejemplos: Crear dos tareas. Después de que uno se ejecuta por completo, luego de esperar 2000 milisegundos, se ejecuta la segunda tarea
Nota: el IDE en línea no funciona correctamente en el método sleep().
Java
// Java program do two FutureTask // using Runnable Interface import java.util.concurrent.*; import java.util.logging.Level; import java.util.logging.Logger; class MyRunnable implements Runnable { private final long waitTime; public MyRunnable(int timeInMillis) { this.waitTime = timeInMillis; } @Override public void run() { try { // sleep for user given millisecond // before checking again Thread.sleep(waitTime); // return current thread name System.out.println(Thread .currentThread() .getName()); } catch (InterruptedException ex) { Logger .getLogger(MyRunnable.class.getName()) .log(Level.SEVERE, null, ex); } } } // Class FutureTaskExample execute two future task class FutureTaskExample { public static void main(String[] args) { // create two object of MyRunnable class // for FutureTask and sleep 1000, 2000 // millisecond before checking again MyRunnable myrunnableobject1 = new MyRunnable(1000); MyRunnable myrunnableobject2 = new MyRunnable(2000); FutureTask<String> futureTask1 = new FutureTask<>(myrunnableobject1, "FutureTask1 is complete"); FutureTask<String> futureTask2 = new FutureTask<>(myrunnableobject2, "FutureTask2 is complete"); // create thread pool of 2 size for ExecutorService ExecutorService executor = Executors.newFixedThreadPool(2); // submit futureTask1 to ExecutorService executor.submit(futureTask1); // submit futureTask2 to ExecutorService executor.submit(futureTask2); while (true) { try { // if both future task complete if (futureTask1.isDone() && futureTask2.isDone()) { System.out.println("Both FutureTask Complete"); // shut down executor service executor.shutdown(); return; } if (!futureTask1.isDone()) { // wait indefinitely for future // task to complete System.out.println("FutureTask1 output = " + futureTask1.get()); } System.out.println("Waiting for FutureTask2 to complete"); // Wait if necessary for the computation to complete, // and then retrieves its result String s = futureTask2.get(250, TimeUnit.MILLISECONDS); if (s != null) { System.out.println("FutureTask2 output=" + s); } } catch (Exception e) { Sysmtem.out.println("Exception: " + e); } } } }
Producción:
FutureTask1 output=FutureTask1 is complete Waiting for FutureTask2 to complete Waiting for FutureTask2 to complete Waiting for FutureTask2 to complete Waiting for FutureTask2 to complete FutureTask2 output=FutureTask2 is complete Both FutureTask Complete
Referencia :