1

I am new to Completable Futures and trying to understand on which thread a callback registered on CompletableFuture constructed using the the Constructor (new CompletableFuture())

For example:

CompletableFuture<String> future =
        CompletableFuture.supplyAsync(() -> {
            //...
        }, pool);
CompletableFuture<Integer> intFuture =
    future.thenApply(s -> s.length());

Transformation in thenApply() is registered and it will be executed immediately after task completion in the same thread as the task.

CompletableFuture<String> future = new CompletableFuture();
CompletableFuture<Integer> intFuture =
    future.thenApply(s -> s.length());
future.complete("hello");

Transformation in thenApply() is registered and on which thread will it be executed once the task is completed using future.complete("hello")? Will it be executed on the main thread or will it be executed on ForkJoinPool.commonPool()?

KraZy
  • 87
  • 6

1 Answers1

3

Only Async methods are executed by new thread, so in your case thenApply is executed by main thread

All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool() (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task).

public class TestMain {

public static void main(String[] args) {

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
        System.out.println(Thread.currentThread().getName());
        return "hello";
    });
    CompletableFuture<Integer> intFuture = future.thenApply(s -> {
        System.out.println(Thread.currentThread().getName());
        return s.length();
    });

    CompletableFuture<Integer> intFuture2 = future.thenApply(s -> {
        System.out.println(Thread.currentThread().getName());
        return s.length();
        });
       future.complete("hello");

     }

 }

Output

ForkJoinPool.commonPool-worker-1
main
main
Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
  • seem wrong, non-async method TRY (not 100%) run in the same thread as the parent CompleteableFuture, async method always run in ForkJoinPool.commonPool thread, if you want always run in main thread, you must supply custom executor – Yessy Dec 12 '20 at 07:19
  • 1
    There’s no sense in citing something that does not apply here, to back a statement that is not contained in the cite. Your output shows one scenario, when the future happens to be completed already when `thenApply` is invoked. Obviously, the result can’t be the same when the future is not yet completed at this point. The function may get evaluated by the thread completing the previous future instead, but actually [it’s even more complicated](https://stackoverflow.com/a/46062939/2711488). – Holger Mar 11 '21 at 10:50