Created
May 3, 2023 04:22
-
-
Save mihai-vasilache/188b168cfc931116824841c0f4a27e93 to your computer and use it in GitHub Desktop.
Createa CompletableFuture from a Future, or Callable. It can be added also from Runnable wrapping into a Callable<Void> that returns null
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.xxx.util; | |
| import java.util.concurrent.Callable; | |
| import java.util.concurrent.CompletableFuture; | |
| import java.util.concurrent.ExecutionException; | |
| import java.util.concurrent.ExecutorService; | |
| import java.util.concurrent.Executors; | |
| import java.util.concurrent.ForkJoinPool; | |
| import java.util.concurrent.Future; | |
| /** | |
| - copied from https://stackoverflow.com/questions/23301598/transform-java-future-into-a-completablefuture#23302308 | |
| - unfortunately not tested enough | |
| - saved more for me. | |
| **/ | |
| public class CreateCompletableFuture { | |
| public static <T> CompletableFuture<T> fromRunnable(Callable<T> callable) throws Exception { | |
| ExecutorService executor = Executors.newSingleThreadExecutor(); | |
| Future<T> future = executor.submit(callable); | |
| CompletableFuture completableFuture = CreateCompletableFuture.fromFuture(future); | |
| executor.shutdown(); | |
| return completableFuture; | |
| } | |
| public static <T> CompletableFuture<T> fromFuture(Future<T> future) { | |
| if (future.isDone()) { | |
| return transformDoneFuture(future); | |
| } | |
| return CompletableFuture.supplyAsync(() -> { | |
| try { | |
| if (!future.isDone()) { | |
| awaitFutureIsDoneInForkJoinPool(future); | |
| } | |
| return future.get(); | |
| } catch (ExecutionException e) { | |
| throw new RuntimeException(e); | |
| } catch (InterruptedException e) { | |
| Thread.currentThread().interrupt(); | |
| throw new RuntimeException(e); | |
| } | |
| }); | |
| } | |
| private static <T> CompletableFuture<T> transformDoneFuture(Future<T> future) { | |
| CompletableFuture<T> cf = new CompletableFuture<>(); | |
| T result; | |
| try { | |
| result = future.get(); | |
| } catch (Throwable ex) { | |
| cf.completeExceptionally(ex); | |
| return cf; | |
| } | |
| cf.complete(result); | |
| return cf; | |
| } | |
| private static void awaitFutureIsDoneInForkJoinPool(Future<?> future) throws InterruptedException { | |
| ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker() { | |
| @Override | |
| public boolean block() throws InterruptedException { | |
| try { | |
| future.get(); | |
| } catch (ExecutionException e) { | |
| throw new RuntimeException(e); | |
| } | |
| return true; | |
| } | |
| @Override | |
| public boolean isReleasable() { | |
| return future.isDone(); | |
| } | |
| }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment