que programación programacion platzi mejor lenguaje cuál cual aprender java java-8 future

programación - platzi java



Transforme el futuro de Java en un futuro completable (4)

Java 8 presenta CompletableFuture , una nueva implementación de Future que se puede componer (incluye un grupo de métodos thenXxx). Me gustaría utilizar esto de manera exclusiva, pero muchas de las bibliotecas que deseo utilizar solo devuelven instancias Future no compibles.

¿Hay alguna manera de concluir las instancias Future devueltas dentro de un CompleteableFuture para que pueda componerlo?


Hay una manera, pero no te gustará. El siguiente método transforma un Future<T> en un CompletableFuture<T> :

public static <T> CompletableFuture<T> makeCompletableFuture(Future<T> future) { return CompletableFuture.supplyAsync(() -> { try { return future.get(); } catch (InterruptedException|ExecutionException e) { throw new RuntimeException(e); } }); }

Obviamente, el problema con este enfoque es que, para cada futuro , un hilo se bloqueará para esperar el resultado del futuro, lo que contradice la idea de futuro. En algunos casos, podría ser posible hacerlo mejor. Sin embargo, en general, no hay solución sin esperar activamente el resultado del futuro .


Permítanme sugerir otra opción (con suerte, mejor): https://github.com/vsilaev/java-async-await/tree/master/com.farata.lang.async.examples/src/main/java/com/farata /concurrente

En resumen, la idea es la siguiente:

  1. Introduzca la interfaz CompletableTask<V> : la unión de CompletionStage<V> + RunnableFuture<V>
  2. Warp ExecutorService para devolver CompletableTask de los métodos de submit(...) (en lugar de Future<V> )
  3. Hecho, tenemos futuros convertibles Y compostables.

La implementación utiliza una implementación alternativa de CompletionStage (preste atención, CompletionStage en lugar de CompletableFuture):

Uso:

J8ExecutorService exec = J8Executors.newCachedThreadPool(); CompletionStage<String> = exec .submit( someCallableA ) .thenCombineAsync( exec.submit(someCallableB), (a, b) -> a + " " + b) .thenCombine( exec.submit(someCallableC), (ab, b) -> ab + " " + c);


Si la biblioteca que desea utilizar también ofrece un método de estilo de devolución de llamada además del estilo Futuro, puede proporcionarle un controlador que complete el CompletableFuture sin ningún bloqueo adicional de subprocesos. Al igual que:

AsynchronousFileChannel open = AsynchronousFileChannel.open(Paths.get("/some/file")); // ... CompletableFuture<ByteBuffer> completableFuture = new CompletableFuture<ByteBuffer>(); open.read(buffer, position, null, new CompletionHandler<Integer, Void>() { @Override public void completed(Integer result, Void attachment) { completableFuture.complete(buffer); } @Override public void failed(Throwable exc, Void attachment) { completableFuture.completeExceptionally(exc); } }); completableFuture.thenApply(...)

Sin la devolución de llamada, la única otra forma en que veo resolver esto es usar un ciclo de sondeo que coloca todas las comprobaciones de Future.isDone() en un solo hilo y luego invocando completar cada vez que se puede obtener un futuro.


Publiqué un pequeño proyecto de futuro que trata de hacer una mejor manera que la respuesta directa .

La idea principal es utilizar el único hilo (y, por supuesto, no solo un ciclo de giro) para verificar todos los estados futuros en el interior, lo que ayuda a evitar el bloqueo de un hilo de un grupo para cada transformación Future -> CompletableFuture.

Ejemplo de uso:

Future oldFuture = ...; CompletableFuture profit = Futurity.shift(oldFuture);