10

I just started looking into Java's CompletableFuture and a little bit confused on whether this is truly asynchronous (i.e running on one thread concurrently) or spanning multiple threads (Parallel).

For example, suppose I'd like to make 1000 different service calls. Suppose further that each service call can be made asynchronously. When using CompletableFuture, will the JVM make 1000 separate threads (assuming the JVM allows for this many threads), or execute all of these requests in one thread? Or is it doing a bit of both? Using some threads to execute those requests asynchronously?

What I want to do is something like this (in Python): https://pawelmhm.github.io/asyncio/python/aiohttp/2016/04/22/asyncio-aiohttp.html

is there a way to execute multiple requests/operations on the same thread in Java asynchronously?

lorenzocastillo
  • 985
  • 3
  • 13
  • 24

2 Answers2

8

As is explained in the javadoc

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

So a threadpool is used, either implicitly (unless you have a single core machine in which case the threads aren't pooled) or explicitly. In your case you would get to control the amount of threads used by using an explicit Executor (e.g. ThreadPoolExecutor) with the amount of threads you want (most likely a lot less than 1000).

The calls cannot share a single thread (the calling thread), as Java doesn't have the capability for what people these days understand by asynchronous due to the popular async/await paradigm (i.e. the fictional "truly asynchronous" term - synchronous vs. asynchronous is independent of threads, but asynchronicity can be implemented with threads, as it is done in CompletableFuture).

With the HttpClient introduced in Java 11 (as incubator module in 9), it's possible to perform asynchronous requests with a threadpool using CompletableFutures in the "standard" way. If you're looking to minimize the thread count, you'll have to switch to reactive programming and use something like Spring's WebClient for the requests.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • So, is there not a way for Java to fire off multiple requests on the same thread, asynchronously? – lorenzocastillo Aug 01 '17 at 02:12
  • See added last paragraph. – Kayaman Aug 01 '17 at 05:52
  • So how does one handle such a use case of making huge amounts of calls to an API ? It would be nice if say we have to make 100 calls, then we make calls back to back which will take few ms to schedule all 100 calls and as API calls are finishing, we join all to get the final result. Spinning up 100 threads where each would just wait and do nothing is inefficient. Making more than 1 call (using a thread pool of < 100) in single thread is again inefficient because first call will block the subsequent calls. – Prakhar Varshney Jun 18 '22 at 05:43
  • @PrakharVarshney see edits. Besides 100 threads is nothing on large server hardware, so it all depends on your use cases. – Kayaman Jun 18 '22 at 11:30
3

If you schedule your computation without specifying a thread-pool, the fork-join common pool would be used, otherwise you can specify your own Executor to supplyAsync and choose a size that fits your need.

Sleiman Jneidi
  • 22,907
  • 14
  • 56
  • 77