What are the ways to pass threadpoolexecutor to CompletableFuture?
I would strongly recommend against it but if you really want to you can use reflection to change the thread pool used by completable future.
public static void main(String[] args) throws Exception {
// Prints ForkJoinPool.commonPool-worker-1
CompletableFuture<Void> c = CompletableFuture.runAsync(() -> System.out.println(Thread.currentThread().getName()));
c.get();
setFinalStatic(CompletableFuture.class.getDeclaredField("asyncPool"), Executors.newFixedThreadPool(10));
// Prints pool-1-thread-1
c = CompletableFuture.runAsync(() -> System.out.println(Thread.currentThread().getName()));
c.get();
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
setFinalStatic
is taken from https://stackoverflow.com/a/3301720/1398418
There is no standard way for replacing the default executor for all CompletableFuture
instances. But since Java 9, you can define a default executor for subclasses. E.g. with
public class MyCompletableFuture<T> extends CompletableFuture<T> {
static final Executor EXEC = r -> {
System.out.println("executing "+r);
new Thread(r).start();
};
@Override
public Executor defaultExecutor() {
return EXEC;
}
@Override
public <U> CompletableFuture<U> newIncompleteFuture() {
return new MyCompletableFuture<>();
}
public static CompletableFuture<Void> runAsync(Runnable runnable) {
Objects.requireNonNull(runnable);
return supplyAsync(() -> {
runnable.run();
return null;
});
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return new MyCompletableFuture<U>().completeAsync(supplier);
}
}
you did all necessary steps for defining the default executor for all chained stages of the MyCompletableFuture
. The executor hold in EXEC
only serves as an example, producing a printout when used, so when you use that example class like
MyCompletableFuture.supplyAsync(() -> "test")
.thenApplyAsync(String::toUpperCase)
.thenAcceptAsync(System.out::println);
it will print
executing java.util.concurrent.CompletableFuture$AsyncSupply@65ab7765
executing java.util.concurrent.CompletableFuture$UniApply@119d7047
executing java.util.concurrent.CompletableFuture$UniAccept@404b9385
TEST