Buscando una forma de quedarme esperando en el código al resultado de otra operación, di con las interfaces ExecutorService, Callable y Future. Estas interfaces nos permitirán realizar operaciones en hilos paralelos y gestionar el resultado de la operación fácilmente.
Para ello haremos uso de las siguientes interfaces:
- ExecutorService:
Nos permitirá crear un hilo/s de ejecución paralela. Estos hilos podrán ejecutar una instancia de tipo Callable/Runnable. Para Runnable usará el método execute y para Callable el método submit.
Además también nos permitirá conocer el estado de los hilos de ejecución, pararlos o esperar a su terminación.
- Executors
La clase de utilidad que nos provee además de distintos métodos para crear un pool de hilos: simples, con cache, parametrizados, etc.
- Callable:
Nos permitirá crear una lógica y que ésta sea invocada a través de un ExecutorService. La diferencia principal respecto a la más conocida Runnable, es que con Callable podremos devolver un valor asociado a la lógica que realicemos.
- Future:
Nos permite manejar el resultado de una operación asíncrona. Pone a nuestra disposición diferentes métodos para comprobar el resultado de la operación y el flujo de esta.
Con isDone, comprobaremos si el hilo asociado ha terminado ya y con isCancelled si ha sido cancelado. Con get, obtendremos el valor de la operación asíncrona.
Ahora veámoslo todo en un único ejemplo. En el crearemos un pool de hilos de ejecución básico que llamará a un método 'complicado' en un hilo paralelo. Tras llamar al hilo secundario, el hilo principal se quedará a la espera e iremos comprobando si el hilo secundario a terminado gracias al método isDone. Obteniendo por último su valor con get, tras una respuesta positiva.
ExecutorService executor = Executors.newSingleThreadExecutor(); Callable<Double> doToughOperation = () -> { TimeUnit.SECONDS.sleep(2); return Math.random(); }; Future<Double> futureValue = executor.submit(doToughOperation); while (!futureValue.isDone()) { System.out.println("Waiting for future value"); TimeUnit.MILLISECONDS.sleep(500); } System.out.println("End tough operation ended with result: " + futureValue.get());
Este programa mostraría la siguiente ejecución:
Waiting for future value Waiting for future value Waiting for future value Waiting for future value End tough operation finally with result: 0.9030054906859435
No hay comentarios:
Publicar un comentario