Skip to content

Instantly share code, notes, and snippets.

@mihai-vasilache
Created May 3, 2023 04:22
Show Gist options
  • Select an option

  • Save mihai-vasilache/188b168cfc931116824841c0f4a27e93 to your computer and use it in GitHub Desktop.

Select an option

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
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